Heinrich Apfelmus慷慨地插入this问题。我曾考虑使用accumB
作为解决方案,但认为会出现类型错误。无论如何,尝试了他的建议后,我确实收到了一个类型错误。功能反应型香蕉型混淆
let bGameState :: Behavior t GameState
bGameState = accumB initialGS $ updateGS <$ eInput
yields the error
Couldn't match expected type `GameState'
with actual type `PlayerCommand'
Expected type: GameState -> GameState
Actual type: PlayerCommand -> GameState -> GameState
In the first argument of `(<$)', namely `updateGS'
In the second argument of `($)', namely `updateGS <$ eInput'
于是我研究(<$)
,并与部分应用程序搞乱身边。看着他的建议例子。我做的越多,我认为上面的代码应该的工作,我对它为什么不工作感到困惑。
这就是我认为应该发生的事情:
因为(<$)
是类型(<$) :: a -> f b -> f a
和updateGS类型为updateGS :: PlayerCommand -> GameState -> GameState
和eInput
类型为Event t PlayerCommand
的则不宜updateGS <$ eInput
收益率
Event t (GameState -> GameState)
?
我的推理在某处存在缺陷,有人可以指出哪里?
更新:当我尝试使用(<$>)
我收到以下错误
outline.hs:158:21:
Could not deduce (t ~ t1)
from the context (Frameworks t)
bound by a type expected by the context:
Frameworks t => Moment t()
at outline.hs:(153,42)-(159,93)
`t' is a rigid type variable bound by
a type expected by the context: Frameworks t => Moment t()
at outline.hs:153:42
`t1' is a rigid type variable bound by
the type signature for bGameState :: Behavior t1 GameState
at outline.hs:158:8
Expected type: Behavior t1 GameState
Actual type: Behavior t GameState
In the expression: accumB initialGS $ updateGS <$> eInput
In an equation for `bGameState':
bGameState = accumB initialGS $ updateGS <$> eInput
作参考,这里是全功能
makeNetworkDescription :: AddHandler PlayerCommand -> IO EventNetwork
makeNetworkDescription addCommandEvent = compile $ do
eInput <- fromAddHandler addCommandEvent
let bCommand = stepper Null eInput
eCommandChanged <- changes bCommand
let bGameState :: Behavior t GameState
bGameState = accumB initialGS $ updateGS <$> eInput
reactimate $ (\n -> appendFile "output.txt" ("Command is " ++ show n)) <$>
eCommandChanged
第二个问题与第一个无关。尝试从'bGameState'中删除类型签名 - 它太多态了('t'上有一个隐含的'forall')。 – hammar
再次感谢哈马尔。 –