
Hi Dan, You have written a great explanation of how ListT works by writing out its definitions in an interesting way! Dan Piponi wrote:
A slightly different approach that doesn't use anything unsafe: A list of type [Char] is essentially a solution to the equation X = Maybe (Char,X)
Yes. In fact, the type data Y a = Y (Maybe (a, Y a)) is exactly equivalent to the type [a].
...to intersperse IO along the computation of the list... define data X = X { unX :: IO (Maybe (Char,X)) }
So that is exactly equivalent to the type ListT IO Char.
test = X $ do a <- getChar if a=='q' then return Nothing else return (Just (a,test))
That translates to: test = do a <- liftIO getChar guard $ a /= 'q' return $ a `mplus` test
test2 :: X -> IO () test2 test = do a <- unX test case a of Nothing -> return () Just (a,b) -> do print a test2 b
Translation: test2 = runListT . mapM (liftIO print) Regards, Yitz