I wonder how you would do this with type familes...<br><br><br><br><div class="gmail_quote">On Tue, Apr 14, 2009 at 2:39 PM, Arthur Chan <span dir="ltr">&lt;<a href="mailto:baguasquirrel@gmail.com">baguasquirrel@gmail.com</a>&gt;</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;">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&#39;t figure out how to tell it that...<br>
<br><br><br>{-# LANGUAGE GeneralizedNewtypeDeriving, NoMonomorphismRestriction, FunctionalDependencies, MultiParamTypeClasses #-}<div class="im"><br><br>import IO<br>import Control.Monad.Reader<br><br><br>class (Monad n) =&gt; Doohickey n where<br>

    putRecord :: String -&gt; n ()<br><br></div>class (Monad m, Doohickey n) =&gt; Toplevel m n | m -&gt; n where<br>    foo :: FilePath -&gt; n a -&gt; 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<div class="im"><br>    foo  s k = do<br>      f &lt;- liftIO $ openFile s AppendMode<br></div>      runReaderT (runIODoohickey k) f<div class="im">
<br>
<br><br>myDoohickey = do<br>  putRecord &quot;foo&quot;<br>  putRecord &quot;bar&quot;<br><br>myOtherDoohickey = do<br>  putRecord &quot;hello&quot;<br>  putRecord &quot;world&quot;<br>  return True<br><br><br><br><br></div>
<div><div></div><div class="h5"><div class="gmail_quote">
On Tue, Apr 14, 2009 at 2:05 PM, Arthur Chan <span dir="ltr">&lt;<a href="mailto:baguasquirrel@gmail.com" target="_blank">baguasquirrel@gmail.com</a>&gt;</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&#39;s my contrived example that threw the error.<br><br>If you go into ghci, and do a `:t (foo&#39; &quot;blah&quot; myDoohickey)`, you will get the type signature &quot;IO ()&quot;.<br>Doing the same for myOtherDoohickey returns &quot;IO True&quot;<br>


<br>So you would think that you&#39;d be able to uncomment the code that makes IO an instance of Toplevel.  foo&#39; is a function that allows IO to run monadic values of type Doohickey.  But it doesn&#39;t work.<br><br>

<br>
---<br><br>import IO<br>import Control.Monad.Reader<br><br><br>class (Monad n) =&gt; Doohickey n where<br>    putRecord :: String -&gt; n ()<br><br>class (Monad m) =&gt; Toplevel m where<br>    foo :: (Doohickey n) =&gt; FilePath -&gt; n a -&gt; 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&#39; s k = do<br>


  f &lt;- liftIO $ openFile s AppendMode<br>  runReaderT (runIOToplevelT k) f<br><br>--instance Toplevel IO where<br>--  foo = foo&#39;<br><br>myDoohickey = do<br>  putRecord &quot;foo&quot;<br>  putRecord &quot;bar&quot;<br>


<br>myOtherDoohickey = do<br>  putRecord &quot;hello&quot;<br>  putRecord &quot;world&quot;<br>  return True<div><div></div><div><br><br><br><div class="gmail_quote">On Mon, Apr 13, 2009 at 7:55 PM, Jason Dusek <span dir="ltr">&lt;<a href="mailto:jason.dusek@gmail.com" target="_blank">jason.dusek@gmail.com</a>&gt;</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&#39;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>
</div></div></blockquote></div><br>