了解Purescript Eff Monad并做阻拦

时间:2017-01-12 06:03:15

标签: haskell purescript

我试图理解为什么以下内容在Purescript中不起作用。我有一种感觉,它也可以由Haskell社区回答,因此我已经交叉列出了它。

一般要点是:

如果我有do块,我可以不投入一次性价值吗?在这个例子中,我试图在一系列monadic计算的中间记录一些东西(类似于Haskell的print)。

main = do
    a <- someAction1
    b <- someAction2
    _ <- log "here is a statement I want printed"
    someAction3 a b

具体来说,我有一个功能,它采用以下(来自卤素示例模板项目)

data Query a = ToggleState a

eval :: Query ~> H.ComponentDSL State Query g
eval (Toggle next) = do
    H.modify (\state -> state { isOn = not state.isOn })
    _ <- log "updating the state!"
    pure next

在我看来,这应该像Haskell一样工作

barf :: IO Int
barf = do
  _ <- print "Here I am!"
  return 5

main :: IO ()
main = do
  a <- barf
  _ <- print $ "the value is: " ++ (show a)
  print "done"

具体来说,我得到的错误是monad的类型不匹配

  

在尝试匹配类型为Eff的类型Free时,类型Eff ( "console" :: CONSOLE | t6 )无法匹配Free (HalogenFP t0 { "isOn" :: t1 | t2 } t3 t4)类型...等等...

我知道purescript让我宣称“我在monad中触摸的东西”(即forall e. Eff ( a :: SOMEVAR, b :: SOMEOTHERVAR | eff ) Unit,但我不知道在这种情况下如何做到这一点......

1 个答案:

答案 0 :(得分:6)

如果您使用的是版本为0.12.0的卤素灯,您应该可以使用https://pursuit.purescript.org/packages/purescript-aff-free/3.0.0/docs/Control.Monad.Aff.Free#v:fromEff中的fromEff,如下所示:

data Query a = ToggleState a

eval :: Query ~> H.ComponentDSL State Query g
eval (Toggle next) = do
    H.modify (\state -> state { isOn = not state.isOn })
    _ <- H.fromEff (log "updating the state!")
    pure next

在即将推出liftEff足够的卤素版本(&gt; = 0.13)时,这将会变得更好。

您不能立即使用log的原因是,H.ComponentDSL不是Eff的类型同义词,而是Free,因此您不能简单地混合EffComponentDSL行动。