[Haskell-cafe] Tail Recursion within the IO Monad

Jules Bean jules at jellybean.co.uk
Wed May 16 16:57:57 EDT 2007


Rob Hoelz wrote:
>             item <- linked_list_getdata listPtr
> 	    next <- linked_list_next listPtr
>             cStr <- peek item
>             hStr <- peekCString cStr
>             t <- linkedListToStringList next
>             return (hStr : t)
item <- linked_list_getdata listPtr
next <- linked_list_next listPtr
cStr <- peek item
hStr <- peekCString cStr
fmap (hStr :) linkedListToStringList next

>
> This is just ugly...making the recursive call first, THEN consing the
> value on?  However, this is the only way I could think of doing it.  I
> figure there are three possibilities from here:

I think you're over-valuing tail recursion. It's not an exciting thing 
in a lazy language the way it is in a pure language. The change I made 
above may not result in particularly better code, although it is more 
concise.

>
> And as long as I'm asking, is there some kind of monadic function
> composition operator?  I'd like to clean up the above with something
> like peekCString . peek . linked_list_getdata...

Yes, that's what >>= and =<< are.

hStr <- peekCString =<< peek =<<  linked_list_getdata listPtr

fmap (hStr :) linkedListToStringList =<< linked_list_next listPtr


...or even...

liftM2 (:) (peekCString =<< peek =<<  linked_list_getdata listPtr)
           (linkedListToStringList =<< linked_list_next listPtr)

It's really a matter of taste.... you could turn the arrows round, too.

Jules


More information about the Haskell-Cafe mailing list