为什么`fmap总和Just`typecheck?

Jim*_* Hu 10 haskell functor foldable

我们知道,fmapfmap :: Functor f => (a -> b) -> f a -> f bsumsum :: (Num a, Foldable t) => t a -> a,但下面的代码让我困惑.

> :t (fmap sum Just)
(fmap sum Just) :: Num b => b -> b
> fmap sum Just 3
3
Run Code Online (Sandbox Code Playgroud)

为什么?

Ada*_*ner 11

我想这里可能有两个令人困惑的地方.

第一个,最明显的是,它sum适用于Foldable事物,而不仅仅是列表.因此:

sum (Just 3) == 3
Run Code Online (Sandbox Code Playgroud)

第二个是您正在使用的仿函数实例.由于Just是一个函数,因为这是第二个参数fmap,你使用的是fmap的读者实例,这里定义了它(https://hackage.haskell.org/package/base-4.9.1.0/docs/src/GHC .Base.html#line-638)简单(.).

它看起来很奇怪,并且它不应该进行类型检查,因为你要为fmap提供三个参数,但实际上,(fmap sum Just)的结果是一个函数:

Prelude> :t fmap sum Just
fmap sum Just :: Num b => b -> b  
Run Code Online (Sandbox Code Playgroud)

如果我们替换fmap.,事情开始做一点更有意义.

Prelude> (.) sum Just 3
3

Prelude> (sum . Just) 3
3
Run Code Online (Sandbox Code Playgroud)

哪个是一样的

sum (Just 3)
Run Code Online (Sandbox Code Playgroud)