`mfix` does not work as expected

I expected the following code to call start: , then wait for the user's response before repeating the previous user response and waiting for a new one:

 import System.IO (hFlush, stdout) import Control.Monad.Fix (mfix) f :: [String] -> IO [String] f = mapM $ \x -> putStr x >> putStr ": " >> hFlush stdout >> getLine gx = f ("start":x) main = mfix g 

But after the first line, the error thread blocked indefinitely in an MVar operation .

Why is this and how can I fix it (sorry for the pun)?

+5
source share
2 answers

The reason this cannot work is because in mfix f , any effect in f is executed exactly once. This follows from the tightening rule.

 mfix (\x -> a >>= \y -> fxy) = a >>= \y -> mfix (\x -> fxy) 

in particular

 mfix (\x -> a >> fx) = a >> mfix f 

for any valid instance of MonadFix . Thus, a fixed point is calculated only for a pure (lazily calculated) value inside a monadic action, and not for effects. In your case, using mfix need to print / read characters once so that the input signal is equal to the output, which is impossible. This is not suitable for mfix . You would use mfix with IO , for example, to build a circular data structure in IO , for example, in these examples .

In your case, you should use iterateM_ or something similar, not mfix . see also iteration + forever = iterateM? Repeating the action with feedback .

+7
source

Unfortunately, mfix in the IO monad doesnโ€™t actually work to create lists in parts. This is due to the fact that most of the actions in the IO monad are very strict: they do not produce any part of their result until all the action has been completed. In particular, mapM in IO will not return any part of its list of results until it goes through its entire input list, which leaves mfix without the hope of binding the node in the right direction here.

In the general case, mfix in IO really only works if the bound value is not strictly looked up until the mfix action is mfix . This still has some possible possibilities, such as initializing a data structure with mutable cell cycles using only newIORef .

+4
source

Source: https://habr.com/ru/post/1205796/


All Articles