Yitzchak Gale gale at sefer.org
Tue Jan 23 04:59:58 EST 2007

```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
```