purescript-halogen:通过有效计算修改状态
purescript-halogen: modify state by effectful computation
我想用一个依赖于旧状态的函数来修改我的状态,但也引入了一些随机性。我的函数 f
如下所示:
f :: State -> Eff (random :: RANDOM) State
我想我的状态应该是纯净的,除了使用unsafePerformEff
,我不知道如何摆脱Eff
,所以我这样做了:
eval :: Query ~> H.ComponentDSL State Query g
eval (Tick next) = do
H.modify (unsafePerformEff <<< f)
pure next
这可行,但必须有另一种更安全的方法。我已经将随机效果添加到我的主要功能中:
main :: Eff (H.HalogenEffects (random :: RANDOM)) Unit
但是 eval
应该是什么样子呢?也许 modify
在这里不起作用,还有另一种更新状态的方法?
对我不起作用,因为 f
取决于旧状态。
modify
本身不允许您执行有效的更新,但是可以,您可以使用 get
然后 modify
(或 set
)来执行此操作.改编自另一个随机示例:
module Main where
import Prelude
import Control.Monad.Aff (Aff)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Random (randomInt, RANDOM)
import Halogen as H
import Halogen.HTML.Events.Indexed as HE
import Halogen.HTML.Indexed as HH
import Halogen.Util (runHalogenAff, awaitBody)
type State = { n :: Int }
initialState :: State
initialState = { n: 3 }
data Query a = NewRandom a
ui :: forall eff. H.Component { n :: Int } Query (Aff (random :: RANDOM | eff))
ui =
H.component { render, eval }
where
render :: State -> H.ComponentHTML Query
render state =
HH.button
[ HE.onClick $ HE.input_ NewRandom ]
[ HH.text $ show state.n ]
eval :: Query ~> H.ComponentDSL State Query (Aff (random :: RANDOM | eff))
eval (NewRandom next) = do
state <- H.get
nextState <- H.fromEff (nextRandom state)
H.set nextState
pure next
nextRandom :: State -> Eff (random :: RANDOM | eff) State
nextRandom { n } = do
nextN <- randomInt (n + 1) (n + 10)
pure { n: nextN }
main :: forall eff. Eff (H.HalogenEffects (random :: RANDOM | eff)) Unit
main =
runHalogenAff do
body <- awaitBody
H.runUI ui initialState body
可能导致类型错误的是这个类型签名:
f :: State -> Eff (random :: RANDOM) State
效果行已关闭,这意味着它不会与任何其他行合并,您可能需要这样:
f :: forall eff. State -> Eff (random :: RANDOM | eff) State
我想用一个依赖于旧状态的函数来修改我的状态,但也引入了一些随机性。我的函数 f
如下所示:
f :: State -> Eff (random :: RANDOM) State
我想我的状态应该是纯净的,除了使用unsafePerformEff
,我不知道如何摆脱Eff
,所以我这样做了:
eval :: Query ~> H.ComponentDSL State Query g
eval (Tick next) = do
H.modify (unsafePerformEff <<< f)
pure next
这可行,但必须有另一种更安全的方法。我已经将随机效果添加到我的主要功能中:
main :: Eff (H.HalogenEffects (random :: RANDOM)) Unit
但是 eval
应该是什么样子呢?也许 modify
在这里不起作用,还有另一种更新状态的方法?
f
取决于旧状态。
modify
本身不允许您执行有效的更新,但是可以,您可以使用 get
然后 modify
(或 set
)来执行此操作.改编自另一个随机示例:
module Main where
import Prelude
import Control.Monad.Aff (Aff)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Random (randomInt, RANDOM)
import Halogen as H
import Halogen.HTML.Events.Indexed as HE
import Halogen.HTML.Indexed as HH
import Halogen.Util (runHalogenAff, awaitBody)
type State = { n :: Int }
initialState :: State
initialState = { n: 3 }
data Query a = NewRandom a
ui :: forall eff. H.Component { n :: Int } Query (Aff (random :: RANDOM | eff))
ui =
H.component { render, eval }
where
render :: State -> H.ComponentHTML Query
render state =
HH.button
[ HE.onClick $ HE.input_ NewRandom ]
[ HH.text $ show state.n ]
eval :: Query ~> H.ComponentDSL State Query (Aff (random :: RANDOM | eff))
eval (NewRandom next) = do
state <- H.get
nextState <- H.fromEff (nextRandom state)
H.set nextState
pure next
nextRandom :: State -> Eff (random :: RANDOM | eff) State
nextRandom { n } = do
nextN <- randomInt (n + 1) (n + 10)
pure { n: nextN }
main :: forall eff. Eff (H.HalogenEffects (random :: RANDOM | eff)) Unit
main =
runHalogenAff do
body <- awaitBody
H.runUI ui initialState body
可能导致类型错误的是这个类型签名:
f :: State -> Eff (random :: RANDOM) State
效果行已关闭,这意味着它不会与任何其他行合并,您可能需要这样:
f :: forall eff. State -> Eff (random :: RANDOM | eff) State