Pete Kazmier wrote:

I understand the intent of this code, but I am having a hard time
understanding the implementation, specifically the combination of
'fix', 'flip', and 'interate'.  I looked up 'fix' and I'm unsure how
one can call 'flip' on a function that takes one argument.

If you look at the code, that's not really what's happening. See the embedded anonymous function below?

>  flip fix accum $
>     \iterate accum -> do
>       ...

It's a function of two arguments. All "flip" is doing is switching the order of the arguments to "fix", in this case for readability. If you were to get rid of the "flip", you'd need to remove the "accum" after "fix" and move it after the lambda expression, which would make the expression much uglier to write and read. So all the "flip" is doing here is tidying up the code.

(If you're still confused, look at the difference between forM and mapM. The only reason forM exists is readability when you have - in terms of the amount of screen space they consume - a big function and a small piece of data, just as here.)

As to why it's okay to call "flip" on "fix" at all, look at the types involved.

fix :: (a -> a) -> a
flip :: (a -> b -> c) -> b -> a -> c

By substitution:

flip fix :: a -> ((a -> b) -> a -> b) -> b

In the case above, accum has type a, and the lambda has type
(a -> IO a) -> a -> IO a, and these fit nicely into the type expected by "flip fix".

        <b
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to