<div dir="ltr"><div>I created a minimal example of what I'm trying to do --- in fact, I think this will be better than what I wrote in the first place --- but now I'm baffled by a different error entirely, which is some identifiers not in scope. I'm going to post this anyway, because I suspect the error is related to what the compiler can infer about my instance, which is something I need to understand better.</div><div><br></div><div>Once you get past that error, either it will be working (yay!) or you'll encounter the error about no instance for MonadState which was my original problem.<br></div><div><br></div><div>{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}</div><br><br>import Control.Monad.State<br>import System.Random<br><br>data ReportData t1 t2 = ReportData t1 t2<br><br>-- this is rolling my own state monad with a random generator<br>class Monad m => RandMonad m where<br>   getGen :: m StdGen<br>   putGen :: StdGen -> ()<br><br>-- this is a class of state monad which logs ReportData:<br><br>class Monad m => LogMonad m where<br>   putReport :: ReportData t1 t2 -> m ()<br><br>-- For a particular use case, I declare a type of State monad:<br><br>data MyStateData t1 t2 = MyStateData t1 t2<br>  { theGen     :: StdGen<br>  , theReports :: [ReportData t1 t2]<br>  }<br><br>type MyState t1 t2 = State (MyStateData t1 t2)<br><br>-- And I try to define my instances:<br><br>instance RandMonad (MyState t1 t2) where<br>  getGen   = gets theGen<br>  putGen g = modify (\s -> s { theGen = g})   -- ERROR : theGen not in scope<br><br>instance LogMonad (MyState t1 t2) where<br>  putReport r = modify (\s -> s { theReports = r : theReports s}) -- ERROR: theReports not in scope<br><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 27, 2018 at 10:43 PM, Dennis Raddle <span dir="ltr"><<a href="mailto:dennis.raddle@gmail.com" target="_blank">dennis.raddle@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>okay, will do. It has a lot of details that aren't really necessary to ask the question, but now that I think about it, all that's required of you is to download and try to compile it.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>D<br></div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 27, 2018 at 10:41 PM, Tom Ellis <span dir="ltr"><<a href="mailto:tom-lists-haskell-cafe-2017@jaguarpaw.co.uk" target="_blank">tom-lists-haskell-cafe-2017@<wbr>jaguarpaw.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Your sample code has a few bugs which make it not compile, for example the<br>
following is not valid syntax<br>
<span><br>
    data MyStateData t1 t2 = MyStateData t1 t2<br>
      { theGen :: StdGen<br>
      , theReports :: [StepReport t1 t2]<br>
      }<br>
<br>
</span>and you use "StepReport" when I think you mean "ReportData".  Could you post<br>
a version which is completely working besides the error you are trying to<br>
solve? Otherwise it's rather hard to help.<br>
<br>
Tom<br>
<div><div class="m_-4301539964449687532h5"><br>
<br>
On Wed, Jun 27, 2018 at 10:22:46PM -0700, Dennis Raddle wrote:<br>
> I'm writing a program with several functions, some of which depend on<br>
> certain fields in a state monad, others of which depend on others, but no<br>
> routine needs all the fields.<br>
> <br>
> So I thought I would declare a two classes, one for each type of data need<br>
> that a function has:<br>
> <br>
> -- as an aside, here's an example of data which is parameterized by two<br>
> types.<br>
> <br>
> data ReportData t1 t2 = ...<br>
> <br>
> -- this is rolling my own state monad with a random generator<br>
> class Monad m => RandMonad m where<br>
>    getGen :: m StdGen<br>
>    putGen :: StdGen -> ()<br>
> <br>
> -- this is a class of state monad which logs ReportData:<br>
> <br>
> class Monad m => LogMonad m where<br>
>    putReport :: ReportData t1 t2 -> m ()<br>
> <br>
> For a particular use case, I declare a type of State monad:<br>
> <br>
> data MyStateData t1 t2 = MyStateData t1 t2<br>
>   { theGen :: StdGen<br>
>   , theReports :: [StepReport t1 t2]<br>
>   }<br>
> <br>
> type MyState t1 t2 = State (MyStateData t1 t2)<br>
> <br>
> And I try to define my instances:<br>
> <br>
> instance RandMonad (MyState t1 t2) where<br>
>   getGen = gets theGen<br>
>   putGen g = modify (\s -> s { theGen = g})<br>
> <br>
> instance LogMonad (MyState t1 t2) where<br>
>   putReport r = modify (\s -> s { theReports = r : theReports s})<br>
> <br>
> I get an error on the LogMonad instance, saying that there's no instance<br>
> for (MonadState (MyState t1 t2) (StateT (MyState t1 t2) Identity))<br>
> <br>
> I guess I don't really understand typeclasses once you start using higher<br>
> kinded types, so please enlighten me. Any reading on this subject would be<br>
> helpful, too.<br>
<br>
</div></div>> ______________________________<wbr>_________________<br>
> Haskell-Cafe mailing list<br>
> To (un)subscribe, modify options or view archives go to:<br>
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bi<wbr>n/mailman/listinfo/haskell-caf<wbr>e</a><br>
> Only members subscribed via the mailman list are allowed to post.<br>
<br>
______________________________<wbr>_________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bi<wbr>n/mailman/listinfo/haskell-caf<wbr>e</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div><br></div>
</div></div></blockquote></div><br></div>