Skip to content

Commit

Permalink
Examples and intuition: IORef has been changed to MVar
Browse files Browse the repository at this point in the history
  • Loading branch information
ehamberg committed Sep 9, 2014
1 parent 3b4e970 commit 2655e1c
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion typeclassopedia.md
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,8 @@ Why is this OK? Isn't `fromJust`{.haskell} almost as bad as `unsafePerformIO`{.

To see this from another point of view, we can consider three possibilities. First, if `f` outputs `Nothing`{.haskell} without looking at its argument, then `maybeFix f`{.haskell} clearly returns `Nothing`{.haskell}. Second, if `f` always outputs `Just x`{.haskell}, where `x` depends on its argument, then the recursion can proceed usefully: `fromJust ma`{.haskell} will be able to evaluate to `x`, thus feeding `f`'s output back to it as input. Third, if `f` tries to use its argument to decide whether to output `Just`{.haskell} or `Nothing`{.haskell}, then `maybeFix f`{.haskell} will not terminate: evaluating `f`'s argument requires evaluating `ma`{.haskell} to see whether it is `Just`{.haskell}, which requires evaluating `f (fromJust ma)`{.haskell}, which requires evaluating `ma`{.haskell}, ... and so on.

There are also instances of `MonadFix`{.haskell} for lists (which works analogously to the instance for `Maybe`{.haskell}), for `ST`{.haskell}, and for `IO`{.haskell}. The [instance for `IO`{.haskell}](http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/System-IO.html#fixIO) is particularly amusing: it creates a new `IORef`{.haskell} (with a dummy value), immediately reads its contents using `unsafeInterleaveIO`{.haskell} (which delays the actual reading lazily until the value is needed), uses the contents of the `IORef`{.haskell} to compute a new value, which it then writes back into the `IORef`{.haskell}. It almost seems, spookily, that `mfix`{.haskell} is sending a value back in time to itself through the `IORef`{.haskell} -- though of course what is really going on is that the reading is delayed just long enough (via `unsafeInterleaveIO`{.haskell}) to get the process bootstrapped.
There are also instances of `MonadFix`{.haskell} for lists (which works analogously to the instance for `Maybe`{.haskell}), for `ST`{.haskell}, and for `IO`{.haskell}. The [instance for `IO`{.haskell}](http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/System-IO.html#fixIO) is particularly amusing: it creates a new (empty) `MVar`{.haskell}, immediately reads its contents using `unsafeInterleaveIO`{.haskell} (which delays the actual reading lazily until the value is needed), uses the contents of the `MVar`{.haskell} to compute a new value, which it then writes back into the `MVar`{.haskell}. It almost seems, spookily, that `mfix`{.haskell} is sending a value back in time to itself through the `MVar`{.haskell} -- though of course what is really going on is that the reading is delayed just long enough (via `unsafeInterleaveIO`{.haskell}) to get the process bootstrapped.


> **Exercises**
>
Expand Down

0 comments on commit 2655e1c

Please sign in to comment.