15

我试图理解Monads 中的解释变得困难,我很难弄清楚以下新类型定义:

newtype (FComp g f) x = FComp { unCompose :: g (f x) }

instance (Functor b c f, Functor a b g) => Functor a c (FComp g f) where
  fmap f (FComp xs) = FComp $ fmap (fmap f) xs

我没有看到用括号中的表达式代替类型声明来解释 newtype 的含义。因此,我无法弄清楚 fmap 函数的定义是什么意思。我也不明白为什么定义了 unCompose 字段访问器但从未使用过。我觉得我缺少一些新类型的基本语义。

4

2 回答 2

16

一个小测试:

newtype (FComp g f) x = FComp { unCompose :: g (f x) }
newtype FComp2 g f x = FComp2 { unCompose2 :: g (f x) }

*Main> :i FComp
newtype FComp g f x = FComp {unCompose :: g (f x)}
        -- Defined at Test.hs:34:10
*Main> :i FComp2
newtype FComp2 g f x = FComp2 {unCompose2 :: g (f x)}
    -- Defined at Test.hs:35:9

所以括号真的不会改变任何东西。就像没有他们一样。

至于uncompose,它只是一个解包的名称,newtype而不使数据构造函数显式。在您发布的片段中,他们使用模式匹配,但不想导出实现细节,因此unCompose提供了使用FComp. 这与定义中的相同data,只是需要newtype一个字段而不是0..n

于 2013-07-25T09:01:29.700 回答
11

你可以这样写:

newtype (FComp g f) x = FComp { unCompose :: g (f x) }

像这样:

newtype FComp g f x = FComp (g (f x))
unCompose (FComp it) = it

这是因为类型应用程序具有与普通应用程序相同的句法属性,即:

a b c  = (a b) c

适用于值 a、b、c 和类型 a、b、c。

于 2013-07-25T09:28:54.413 回答