2017-02-15 3 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

대단히 감사합니다. Phil! –

0

기능 when 내 컴퓨터에서 작동하지 않으며,이 내 솔루션입니다.

_ <- modifySTRef ref (if cond then func else id)