4

ハインリッヒ・アプフェルムスはこの問題について寛大に話しかけました。解決策として使うことを考えてい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
4

1 に答える 1

5

コードの何が問題になっていますか

<$>ではなく、を使用する必要があります<$

  • <$>、別名fmapは、右側のイベントの値に関数を適用します。これは、この場合に実行しようとしていることです。
  • <$ 右側のイベントの値を左側のイベントに置き換えて、元のイベントと同時に発生するが、常に同じ値を含むイベントを提供します。

    注:はとx <$ e同じconst x <$> eです。

なぜあなたの推論が間違っているのか

updateGS <$ eInputサブタームのタイプがどこにあるかを判別しようとしています。

(<$)     :: a -> f b -> f a
updateGS :: PlayerCommand -> GameState -> GameState
eInput   :: Event t PlayerCommand

ここで考えてみましょう。どのタイプをインスタンス化する必要abありfますか?

  1. は型を持つ最初updateGSの引数なので、<$a

    a ~ PlayerCommand -> GameState -> GameState
    
  2. 同様に、はタイプを持つeInput2番目の引数であるため、<$f b

    f b ~ Event t PlayerCommand
    

    タイプアプリケーションは左側に関連付けられているためEvent t PlayerCommand、と同じ(Event t) PlayerCommandです。したがって、次のように判断できます。

    f ~ Event t
    b ~ PlayerCommand
    
  3. f a結果のタイプをまとめると、、

    f a ~ Event t (PlayerCommand -> GameState -> GameState)     
    

したがって、updateGS <$ eInput :: Event t (PlayerCommand -> GameState -> GameState)はタイプエラーを説明します。

于 2012-10-25T17:46:05.917 に答える