I seem to have finally solved my own problem, via something I learned from RWH. The solution is to use functional dependencies...<br><br>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...<br>
<br><br><br>{-# LANGUAGE GeneralizedNewtypeDeriving, NoMonomorphismRestriction, FunctionalDependencies, MultiParamTypeClasses #-}<br><br>import IO<br>import Control.Monad.Reader<br><br><br>class (Monad n) => Doohickey n where<br>
putRecord :: String -> n ()<br><br>class (Monad m, Doohickey n) => Toplevel m n | m -> n where<br> foo :: FilePath -> n a -> m a<br><br>newtype IODoohickey a = IODoohickey { runIODoohickey :: ReaderT Handle IO a } deriving (Monad, MonadReader Handle, MonadIO)<br>
<br>instance Doohickey IODoohickey where<br> putRecord = liftIO . putStrLn<br><br>instance Toplevel IO IODoohickey where<br> foo s k = do<br> f <- liftIO $ openFile s AppendMode<br> runReaderT (runIODoohickey k) f<br>
<br><br>myDoohickey = do<br> putRecord "foo"<br> putRecord "bar"<br><br>myOtherDoohickey = do<br> putRecord "hello"<br> putRecord "world"<br> return True<br><br><br><br><br><div class="gmail_quote">
On Tue, Apr 14, 2009 at 2:05 PM, Arthur Chan <span dir="ltr"><<a href="mailto:baguasquirrel@gmail.com">baguasquirrel@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Here's my contrived example that threw the error.<br><br>If you go into ghci, and do a `:t (foo' "blah" myDoohickey)`, you will get the type signature "IO ()".<br>Doing the same for myOtherDoohickey returns "IO True"<br>
<br>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.<br><br>
<br>
---<br><br>import IO<br>import Control.Monad.Reader<br><br><br>class (Monad n) => Doohickey n where<br> putRecord :: String -> n ()<br><br>class (Monad m) => Toplevel m where<br> foo :: (Doohickey n) => FilePath -> n a -> m a<br>
<br>newtype IOToplevelT a = IOToplevelT { runIOToplevelT :: ReaderT Handle IO a } deriving (Monad, MonadReader Handle, MonadIO)<br><br>instance Doohickey IOToplevelT where<br> putRecord = liftIO . putStrLn<br><br>foo' s k = do<br>
f <- liftIO $ openFile s AppendMode<br> runReaderT (runIOToplevelT k) f<br><br>--instance Toplevel IO where<br>-- foo = foo'<br><br>myDoohickey = do<br> putRecord "foo"<br> putRecord "bar"<br>
<br>myOtherDoohickey = do<br> putRecord "hello"<br> putRecord "world"<br> return True<div><div></div><div class="h5"><br><br><br><div class="gmail_quote">On Mon, Apr 13, 2009 at 7:55 PM, Jason Dusek <span dir="ltr"><<a href="mailto:jason.dusek@gmail.com" target="_blank">jason.dusek@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"> Copypasting and loading your code doesn't throw an error. Please,<br>
pastebin an example that demonstrates the error.<br>
<br>
--<br>
<font color="#888888">Jason Dusek<br>
</font></blockquote></div><br>
</div></div></blockquote></div><br>