我试图理解为什么以下内容在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
,但我不知道在这种情况下如何做到这一点......
答案 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
,因此您不能简单地混合Eff
和ComponentDSL
行动。