{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreifg7wvsulgsvit6h6gilg2rnbfw3a2tzi4ixlzkqa4vsj4thp6vn4",
    "uri": "at://did:plc:pi6woz4d47bkuws673w2il2r/app.bsky.feed.post/3mkqmg74hgi72"
  },
  "path": "/t/free-like-data-structure/14012#post_2",
  "publishedAt": "2026-04-30T20:24:44.000Z",
  "site": "https://discourse.haskell.org",
  "tags": [
    "perfect"
  ],
  "textContent": "You can view the normal free monad as a kind of tree structure. If you use the functor `f a = (a, a)` then it actually is just a binary tree. Notably, this tree is not necessarily balanced.\n\nIf you use the same functor `f a = (a, a)` in your free-like structure then you get a classic nested data type encoding of perfect binary trees.\n\nIf you consider `f = State s` then your free-like structure is a stateful computation where you have to specify the exact number of `put` and `get` operations that you will use before hand. In the normal free monad you can use a different number of these operations based on the intermediate results of the operations.\n\nFor example you can write this program with `Free`, but not with your free-like structure:\n\n\n    countdown :: Free (State Int) ()\n    countdown = do\n      x <- get\n      when (x > 0) $ do\n        put (x - 1)\n        countdown\n\n\nIn this program the number of `get` and `put` operations depends on the value of the state you start with.",
  "title": "Free-like data structure:"
}