2017-02-15 6 views
1

例をガードを使用する方法:関数自体が動作は、例のセクションでPurescriptでEffがモナドで8.17可変状態を

import Prelude 

import Control.Monad.Eff (Eff, forE) 
import Control.Monad.ST (ST, newSTRef, readSTRef, modifySTRef) 

simulate :: forall eff h. Number -> Number -> Int -> Eff (st :: ST h | eff) Number 
simulate x0 v0 time = do 
    ref <- newSTRef { x: x0, v: v0 } 
    forE 0 (time * 1000) \_ -> do 
    modifySTRef ref \o -> 
     { v: o.v - 9.81 * 0.001 
     , x: o.x + o.v * 0.001 
     } 
    pure unit 
    final <- readSTRef ref 
    pure final.x 

はシミュレート機能であります良い。 xの値でパーティクルの動きを止めるように修正する必要があるとします。この:次のエラーで

import Prelude 
import Control.MonadPlus (guard) 

import Control.Monad.Eff (Eff, forE) 
import Control.Monad.ST (ST, newSTRef, readSTRef, modifySTRef) 

simulate :: forall eff h. Number -> Number -> Int -> Eff (st :: ST h | eff) Number 
simulate x0 v0 time = do 
    ref <- newSTRef { x: x0, v: v0 } 
    forE 0 (time * 1000) \_ -> do 
    o <- readSTRef ref 
    let v = o.v - 9.81 * 0.001 
    let x = o.x + o.v * 0.001 
    guard (x < 100.0) 
    modifySTRef ref \o -> 
     { v: v 
     , x: x 
     } 
    pure unit 
    final <- readSTRef ref 
    pure final.x 

結果:

No type class instance was found for 

    Control.MonadZero.MonadZero (Eff 
            ("st" :: ST h3 
            | eff4 
            ) 
           ) 
... 

これはguardは全くEffモナドで使用することができないということですか?どのように慣用的なpurescriptに同じ意図を持つコードを書くだろうか?

答えて

2

あなたがguardを使用することはできませんが、どんなMonadで動作whenを、使用することができます。

when (x < 100.0) $ 
    modifySTRef ref \o -> 
    { v: v 
    , x: x 
    } 
+0

素晴らしい、ありがとうございました! –

0

機能whenは自分のコンピュータ上では動作しません、これは私のソリューションです。

_ <- modifySTRef ref (if cond then func else id) 
関連する問題