{
"$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:"
}