【发布时间】:2019-03-24 15:27:36
【问题描述】:
我的数据定义如下:
data FGM a = Pure a | GMAction Integer Integer (PlayerMsg -> FGM a)
data PlayerMsg = Guess Integer | Surrender
deriving (Eq, Show)
FGM代表猜数游戏,2个整数是上下界,a是最后要返回的值,playermsg是玩家的猜测。
我想让 FGM 成为 Functor,所以我试图为它定义一个 fmap。问题是我不知道如何处理 FGM 的(PlayerMsg -> FGM a) 部分。
根据我对给出的测试用例的理解,对于fmap g (someFGM),g 应该只应用于Pure,如果是GMAction,fmap 应该使用PlayerMsg 并生成下一个 FGM,直到它达到Pure.
这是我尝试过的:
instance Functor FGM where
fmap g (Pure a) = Pure (g a)
fmap g (GMAction upper lower thing) = GMAction upper lower (fmap g (\x -> case (thing x) of
Pure a -> Pure a
GMAction u l t -> GMAction u l t))
但是当我尝试对此进行测试时,我得到了这个错误:
Occurs check: cannot construct the infinite type:
b ~ FGM b
Expected type: PlayerMsg -> FGM b
Actual type: PlayerMsg -> b
In the third argument of 'GMAction', namely '(fmap g (\x -> case (thing x) of
Pure a -> Pure a
GMAction u l t -> GMAction u l t))'
In the expression:...
我也试过
fmap g (GMAction upper lower thing) = GMAction upper lower (fmap g thing)
得到了同样的错误。
我试图搜索具有像PlayerMsg -> FGM a 这样的参数的数据的示例,但找不到任何东西。 this 有点相似,但对我不起作用(这是我第一个失败的例子)。有人可以帮我定义这个 fmap 或告诉我在哪里了解这个吗?
【问题讨论】:
-
旁注:带有case表达式的lambda等于
thing。
标签: haskell