Haskell 如何为包含函数的函子编写fmap';什么是数据类型定义?

Haskell 如何为包含函数的函子编写fmap';什么是数据类型定义?,haskell,Haskell,我的数据定义如下: data FGM a = Pure a | GMAction Integer Integer (PlayerMsg -> FGM a) data PlayerMsg = Guess Integer | Surrender deriving (Eq, Show) FGM代表一个数字猜测游戏,其中2个整数是上限和下限,a是最终返回的值,playermsg是玩家的猜测。 我想让FGM成为一个函子,所以我试图为它定义一个fmap。问题是我不知道如何处理FGM的(Pla

我的数据定义如下:

data FGM a = Pure a | GMAction Integer Integer (PlayerMsg -> FGM a)
data PlayerMsg = Guess Integer | Surrender
    deriving (Eq, Show)
FGM代表一个数字猜测游戏,其中2个整数是上限和下限,a是最终返回的值,playermsg是玩家的猜测。 我想让FGM成为一个函子,所以我试图为它定义一个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
,但找不到任何内容。有点类似,但对我不起作用(这是我第一个失败的例子)。有人能帮我定义这个fmap或者告诉我从哪里了解这个吗?

试试
fmap g(GMAction upper-lower thing)=GMAction upper-lower((fmap g).thing)
。注意函数的组成;这是必要的,因为您需要对函数的结果进行
fmap

尝试
fmap g(GMAction-upper-lower-thing)=GMAction-upper-lower((fmap-g).thing)
。注意函数的组成;这是必要的,因为您需要对函数的结果进行
fmap

GHC用于派生
Functor
的内置规则足以处理这样的简单情况

{-# LANGUAGE DeriveFunctor #-}
data FGM a = Pure a | GMAction Integer Integer (PlayerMsg -> FGM a) deriving Functor
data PlayerMsg = Guess Integer | Surrender
    deriving (Eq, Show)

GHC用于派生
Functor
的内置规则足以处理这样的简单情况

{-# LANGUAGE DeriveFunctor #-}
data FGM a = Pure a | GMAction Integer Integer (PlayerMsg -> FGM a) deriving Functor
data PlayerMsg = Guess Integer | Surrender
    deriving (Eq, Show)

耶,它成功了!非常感谢。是的,这是错别字,我会编辑它的!非常感谢。是的,这是打字错误,我将编辑它的侧注:带大小写表达式的lambda相当于
东西
。侧注:带大小写表达式的lambda相当于
东西
。真的-尽管我上面给出了答案-这也是我通常使用的。让电脑为你写代码真是太好了@CeilviaC:您还可以看到GHC从带有
-ddump-deriv
标志的
派生
子句生成的代码。(如果您使用的是Stack,这将在您的
.Stack work
目录中生成一个
.dump deriv
文件。)真的-尽管我在上面给出了答案-这也是我通常使用的。让电脑为你写代码真是太好了@CeilviaC:您还可以看到GHC从带有
-ddump-deriv
标志的
派生
子句生成的代码。(如果您使用的是Stack,这将在
.Stack work
目录中生成一个
.dump deriv
文件。)