<div dir="ltr"><div><div>Building up on the exemple below, I have a problem with mixing effectful/effectless computations. For example, this would not compile:<br><br></div><span style="font-family:courier new,monospace">> noEff :: Exp NoEffect ()<br>
</span></div><span style="font-family:courier new,monospace">> noEff = return ()<br></span><div><div><div><div class="gmail_extra"><span style="font-family:courier new,monospace"><br></span></div><div class="gmail_extra">
<span style="font-family:courier new,monospace">> hasEffect :: Exp Effect ()<br></span></div><div class="gmail_extra"><span style="font-family:courier new,monospace">> hasEffect = do<br></span></div><div class="gmail_extra">
<span style="font-family:courier new,monospace">>   noEff                    <--- won't compile<br></span></div><div class="gmail_extra"><span style="font-family:courier new,monospace">>   return ()</span><br>
</div><div class="gmail_extra"><br></div><div class="gmail_extra">But it should: you should be able to run an effectless monad in an effectful one.<br></div><div class="gmail_extra">How to encode this semantic?<br></div><div class="gmail_extra">
I know you can replace the type signature of noEff by: <br><br><span style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">> noEff :: </span>Exp r ()<br><br></span></div><div class="gmail_extra">
But I don't find it so elegant...<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">I suppose you have to encode the semantic in the Bind of the Monad instance:<br><br><span style="font-family:courier new,monospace">> data Exp :: Eff -> * -> * where<br>
>   ...<br>>   Bind1        :: Exp NoEffect a -> (a -> Exp r b) -> Exp r b<br>>   Bind2        :: Exp Effect a -> (a -> Exp r b) -> Exp Effect b</span><br><span style="font-family:courier new,monospace"><br>
</span></div><div class="gmail_extra"><span style="font-family:courier new,monospace">> instance Monad (Exp r) where<br>>    return = Const<br>>    (a :: Exp NoEffect a) >>= f = a `Bind1` f<br>>    (a :: Exp Effect a)   >>= f = a `Bind2` f<br>
</span><br></div><div class="gmail_extra">But this doesn't work:<br><span style="font-family:courier new,monospace">Couldn't match type `r' with 'NoEffect<br>      `r' is a rigid type variable</span><br>
<br></div><div class="gmail_extra">Thanks a lot for the help :) all this thread helped me a lot!!<br><br></div><div class="gmail_extra">Corentin<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Jan 30, 2014 at 8:53 PM, Corentin Dupont <span dir="ltr"><<a href="mailto:corentin.dupont@gmail.com" target="_blank">corentin.dupont@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><br><div class="gmail_quote"><br><div dir="ltr"><div class="im"><div class="gmail_extra">
Oleg: Very interresting, thanks. I have some questions:<br>- What do you mean by "The type Cont Int a describes an impure computation, which may
abort with an Int value, for example". <br></div><div class="gmail_extra">Aborting with an Int value is akin to exceptions?<br></div><div class="gmail_extra">- for me it's not clear when to choose an "applicative" or a "monadic" DSL? Betsides, what's the rational behind the name "let_" (never seen it before)?<br>


</div><div class="gmail_extra"><br></div><div class="gmail_extra"><br>Linsey, Jacques: Thanks for the pointer! I learned about data kinds.<br>I tried to apply your suggestions to add a phantom type parameter to Exp.<br></div>


</div><div class="gmail_extra">I came up to (I dropped the Free monad idea, which seems unrelated to the problem):<div><div class="h5"><br><span style="font-family:courier new,monospace"><br></span></div></div></div></div>
</div></div></blockquote><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div dir="ltr"><div class="gmail_extra">
<div><div class="h5"><span style="font-family:courier new,monospace">> data Eff = Effect | NoEffect<br><br>> -- first type parameter is used to track effects<br>
> data Exp :: Eff -> * -> * where<br>
>   ReadAccount  :: Exp r Int  --ReadAccount can be used in whatever monad (with or without effect)<br>>   WriteAccount :: Exp NoEffect Int -> Exp Effect ()  --WriteAccount takes an effect-less expression, and returns an effectfull expression<br>


>   SetVictory   :: Exp NoEffect Bool -> Exp Effect ()  -- same for SetVictory<br>>   OnTimer      :: Exp Effect () -> Exp Effect () --OnTime can program whatever expression to be triggered every minutes, in particular effectful ones<br>


>   Return       :: a -> Exp r a<br>>   Bind         :: Exp r a -> (a -> Exp r b) -> Exp r b<br><br>This is the (simplified) game state:<div><br><br>> data Game = Game { bankAccount :: Int,<br>
</div>>                    victory     :: Exp NoEffect Bool,<br>
>                    timerEvent  :: Exp Effect ()}<br><br></span></div></div></div><div><div class="h5"><div class="gmail_extra"><span style="font-family:courier new,monospace">> -- victory when account > 100<br>
</span></div><div class="gmail_extra">

<span style="font-family:courier new,monospace">> victoryRule' :: Exp Effect ()<div><br>> victoryRule' = SetVictory $ do<br></div>>   m <- readAccount<br>>   --WriteAccount (return $ m + 1) --won't compile (good)<div>

<br>
>   return (m > 100)<br><br>> --increase my bank account by 1 every minute<br></div>> myTimer :: Exp Effect ()<br>> myTimer = OnTimer $ do<br>>   m <- readAccount<div><br>>   writeAccount (return $ m + 1)<br>


</div></span><br><br></div><div class="gmail_extra">Do you have a better name suggestion for Eff? Other pointers where this idiom is realised??<br></div><div class="gmail_extra">Thanks!!<span><font color="#888888"><br>
</font></span></div><span><font color="#888888"><div class="gmail_extra">Corentin<br>
</div></font></span></div></div></div>
</div><br></div>
</blockquote></div><br></div></div></div></div></div>