[Haskell-beginners] How would you run a monad within another monad?

Arthur Chan baguasquirrel at gmail.com
Tue Apr 14 17:39:56 EDT 2009


I seem to have finally solved my own problem, via something I learned from
RWH.  The solution is to use functional dependencies...

The problem was that the compiler needed to know the relationship between
Doohickeys and Toplevels, and I couldn't figure out how to tell it that...



{-# LANGUAGE GeneralizedNewtypeDeriving, NoMonomorphismRestriction,
FunctionalDependencies, MultiParamTypeClasses #-}

import IO
import Control.Monad.Reader


class (Monad n) => Doohickey n where
    putRecord :: String -> n ()

class (Monad m, Doohickey n) => Toplevel m n | m -> n where
    foo :: FilePath -> n a -> m a

newtype IODoohickey a = IODoohickey { runIODoohickey :: ReaderT Handle IO a
} deriving (Monad, MonadReader Handle, MonadIO)

instance Doohickey IODoohickey where
    putRecord = liftIO . putStrLn

instance Toplevel IO IODoohickey where
    foo  s k = do
      f <- liftIO $ openFile s AppendMode
      runReaderT (runIODoohickey k) f


myDoohickey = do
  putRecord "foo"
  putRecord "bar"

myOtherDoohickey = do
  putRecord "hello"
  putRecord "world"
  return True




On Tue, Apr 14, 2009 at 2:05 PM, Arthur Chan <baguasquirrel at gmail.com>wrote:

> Here's my contrived example that threw the error.
>
> If you go into ghci, and do a `:t (foo' "blah" myDoohickey)`, you will get
> the type signature "IO ()".
> Doing the same for myOtherDoohickey returns "IO True"
>
> So you would think that you'd be able to uncomment the code that makes IO
> an instance of Toplevel.  foo' is a function that allows IO to run monadic
> values of type Doohickey.  But it doesn't work.
>
>
> ---
>
> import IO
> import Control.Monad.Reader
>
>
> class (Monad n) => Doohickey n where
>     putRecord :: String -> n ()
>
> class (Monad m) => Toplevel m where
>     foo :: (Doohickey n) => FilePath -> n a -> m a
>
> newtype IOToplevelT a = IOToplevelT { runIOToplevelT :: ReaderT Handle IO a
> } deriving (Monad, MonadReader Handle, MonadIO)
>
> instance Doohickey IOToplevelT where
>     putRecord = liftIO . putStrLn
>
> foo' s k = do
>   f <- liftIO $ openFile s AppendMode
>   runReaderT (runIOToplevelT k) f
>
> --instance Toplevel IO where
> --  foo = foo'
>
> myDoohickey = do
>   putRecord "foo"
>   putRecord "bar"
>
> myOtherDoohickey = do
>   putRecord "hello"
>   putRecord "world"
>   return True
>
>
>
> On Mon, Apr 13, 2009 at 7:55 PM, Jason Dusek <jason.dusek at gmail.com>wrote:
>
>>  Copypasting and loading your code doesn't throw an error. Please,
>>  pastebin an example that demonstrates the error.
>>
>> --
>> Jason Dusek
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20090414/c3fd4db2/attachment.htm


More information about the Beginners mailing list