<div dir="ltr"><div>Here's the important info:</div> liftMoment :: MonadMoment m => Moment a -> m a<div> instance MonadMoment MomentIO<br></div><div> instance MonadMoment Moment</div><div><br></div><div>So liftMoment gives you a MomentIO or a Moment, not an IO. You need to do something with that.</div><div><br></div><div>From <a href="https://hackage.haskell.org/package/reactive-banana-1.0.0.0/docs/Reactive-Banana-Frameworks.html#v:compile">https://hackage.haskell.org/package/reactive-banana-1.0.0.0/docs/Reactive-Banana-Frameworks.html#v:compile</a><br></div><div> compile :: MomentIO () -> IO EventNetwork<br></div><div><br></div><div>It looks like the intended usage is to compile into an EventNetwork, then use the functions that operate on EventNetwork (like "actuate" to start it). If you need to get a boolean value out, you need another way to do so (such as using reactimate to call a callback)</div><div><br></div><div> -- ryan</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 13, 2015 at 8:48 AM, Michael Litchard <span dir="ltr"><<a href="mailto:michael@schmong.org" target="_blank">michael@schmong.org</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"><p> I think I'm on the right track. I have commented out all test harness code and have changed the signature for <code>bufferPopulated</code></p>
<pre><code><span>bufferPopulated </span><span>::</span><span> UAC </span><span>-></span><span> IO Bool
bufferPopulated ev </span><span>=</span><span> </span><span>do</span><span class=""><span>
</span><span>let</span><span> eInput </span><span>=</span><span> ev </span><span><$</span><span> never
eValidated </span><span>=</span><span> toVAC </span><span><$></span></span><span> eInput
bBufferMap </span><span><-</span><span> liftMoment </span><span>((</span><span>buffer eValidated eClear</span><span>)</span><span> </span><span>::</span><span> Moment </span><span>(</span><span>Behavior BufferMap</span><span>))</span><span>
</span><span class=""><span>let</span><span> r2 </span><span>=</span><span> </span><span>[(</span><span>Just </span><span>$</span><span> BufferMap </span><span>$</span><span> M.insert </span><span>(</span><span>AID </span><span>(</span><span>Data.Text.pack </span><span>"100"</span><span>))</span><span> </span><span>(</span><span>toVAC ev</span><span>)</span><span> </span><span>(</span><span>M.empty </span><span>::</span><span> M.Map AID VAC</span><span>))]</span></span><span>
r1 </span><span><-</span><span> </span><span>(</span><span>interpret </span><span>(</span><span>eBuffer bBufferMap</span><span>)</span><span> </span><span>[])</span><span> </span><span>::</span><span> IO </span><span>[</span><span>Maybe BufferMap</span><span>])</span><span>
return </span><span>$</span><span> r1 </span><span>==</span><span> r2</span></code></pre><div class="gmail_extra"><p>I believe this should work, but here's the error</p>
<pre><code><span>tests</span><span>/</span><span>Spec.hs</span><span>:</span><span>35</span><span>:</span><span>17</span><span>:</span><span>
No </span><span>instance</span><span> for </span><span>(</span><span>MonadMoment IO</span><span>)</span><span> arising from a use </span><span>of</span><span> </span><span>‘</span><span>liftMoment</span><span>’</span><span>
In a stmt </span><span>of</span><span> a </span><span>'d</span><span>o' block</span><span>:</span><span>
bBufferMap </span><span><-</span><span> liftMoment
</span><span>((</span><span>buffer eValidated eClear</span><span>)</span><span> </span><span>::</span><span> Moment </span><span>(</span><span>Behavior BufferMap</span><span>))<br><br></span></code></pre><p>Let's take a look at <code>MonadMoment</code> from <code>Reactive.Banana.Combinators</code></p>
<code><span>class</span><span> Monad m </span><span>=></span><span> MonadMoment m </span><span>where</span><span><br> An </span><span>instance</span><span> </span><span>of</span><span> the MonadMoment </span><span>class</span><span> denotes a computation that happens at one particular moment </span><span>in</span><span> time</span><span>.<br></span><span> Unlike the Moment monad</span><span>,</span><span> it need not be pure anymore</span><span>.</span><span><br> Methods<br> liftMoment </span><span>::</span><span> Moment a </span><span>-></span><span> m a<br> Instances<br> MonadMoment MomentIO<br> MonadMoment Moment<br><br></span></code><code>m</code> can be any <code>Monad</code>, <code>IO</code> is a <code>Monad</code>. so <code>liftMoment</code> should lift the <code>Moment Behavior (BufferMap)</code> to <code>IO Behavior (BufferMap)</code> , why doesn't it. What's wrong with my reasoning?<div><div class="h5"><br><pre><br></pre><div class="gmail_quote">On Fri, Nov 13, 2015 at 7:16 AM, Michael Litchard <span dir="ltr"><<a href="mailto:michael@schmong.org" target="_blank">michael@schmong.org</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"><pre>Below is some test code I am writing for my game, the link to the entire codebase, the error message and some discussion
main :: IO ()
main = defaultMain
[ testGroup "EventNetwork Input"
[testBuffer "bBuffer" Populated]
]
testBuffer :: String -> BufferState -> Test
testBuffer name Populated =
testCase name $ assert $ bufferPopulated (UAC (PlayerCommand (Move (ToPlanetName Mongo)) (AID (Data.Text.pack "100"))))
testBuffer name Empty =
testCase name $ assert $ bufferEmptied (UAC (PlayerCommand (Move (ToPlanetName Mongo)) (AID (Data.Text.pack "100"))))
bufferPopulated :: UAC -> MomentIO Bool
bufferPopulated ev = do
let eInput = ev <$ never
eValidated = toVAC <$> eInput
bBufferMap <- (buffer eValidated eClear) :: MomentIO (Behavior BufferMap)
let r2 = [(Just $ BufferMap $ M.insert (AID (Data.Text.pack "100")) (toVAC ev) (M.empty :: M.Map AID VAC))]
r1 <- liftIO $ ((interpret (eBuffer bBufferMap) []) :: IO [Maybe BufferMap])
return $ r1 == r2
bufferEmptied :: UAC -> MomentIO Bool
bufferEmptied ev = undefined
eBuffer :: Behavior BufferMap -> Event a -> Event BufferMap
eBuffer bBufferMap nvr =
bBufferMap <@ (() <$ nvr)
eClear = Clear <$ (() <$ never)
When I run stack build I get
tests/Spec.hs:26:19:
No instance for (Test.HUnit.Base.Assertable (MomentIO Bool))
arising from a use of ‘assert’
In the expression: assert
In the second argument of ‘($)’, namely
‘assert
$ bufferPopulated
(UAC
(PlayerCommand (Move (ToPlanetName Mongo)) (AID (pack "100"))))’
In the expression:
testCase name
$ assert
$ bufferPopulated
(UAC
(PlayerCommand (Move (ToPlanetName Mongo)) (AID (pack "100"))))
The problem lies with buffer. It relies on accumB which requires the MomentIO monad. I considered writing an
instance for Assertable, but I think that's a red-herring and the answer lies elsewhere. I need to reconcile the
fact that assert wants an IO Bool, but accumB wants a MomentIO. Maybe I do need to write an instance for Assertable.
Here's the link to the project:
<a href="https://github.com/mlitchard/emporos/tree/banana-1.0.0/src" target="_blank">https://github.com/mlitchard/emporos/tree/banana-1.0.0/src</a></pre></div>
</blockquote></div><br></div></div></div></div>
<br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
<br></blockquote></div><br></div>