为什么 `fmap sum Just` 会进行类型检查?
Why does `fmap sum Just` typecheck?
我们知道 fmap
是 fmap :: Functor f => (a -> b) -> f a -> f b
而 sum
是 sum :: (Num a, Foldable t) => t a -> a
,但下面的代码让我感到困惑。
> :t (fmap sum Just)
(fmap sum Just) :: Num b => b -> b
> fmap sum Just 3
3
为什么?
我认为这里可能有两个令人困惑的地方。
首先,最明显的是,sum
适用于 Foldable
事物,而不仅仅是列表。因此:
sum (Just 3) == 3
第二个是您正在使用的仿函数实例。由于 Just
是一个函数,因为它是 fmap
的第二个参数,您正在使用 fmap 的 reader 实例,它在此处 (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
如果我们用 .
替换 fmap
,事情开始变得更有意义了。
Prelude> (.) sum Just 3
3
Prelude> (sum . Just) 3
3
与
相同
sum (Just 3)
我们知道 fmap
是 fmap :: Functor f => (a -> b) -> f a -> f b
而 sum
是 sum :: (Num a, Foldable t) => t a -> a
,但下面的代码让我感到困惑。
> :t (fmap sum Just)
(fmap sum Just) :: Num b => b -> b
> fmap sum Just 3
3
为什么?
我认为这里可能有两个令人困惑的地方。
首先,最明显的是,sum
适用于 Foldable
事物,而不仅仅是列表。因此:
sum (Just 3) == 3
第二个是您正在使用的仿函数实例。由于 Just
是一个函数,因为它是 fmap
的第二个参数,您正在使用 fmap 的 reader 实例,它在此处 (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
如果我们用 .
替换 fmap
,事情开始变得更有意义了。
Prelude> (.) sum Just 3
3
Prelude> (sum . Just) 3
3
与
相同sum (Just 3)