【问题标题】:Why does `fmap sum Just` typecheck?为什么`fmap sum Just`类型检查?
【发布时间】:2017-04-10 03:46:38
【问题描述】:

我们知道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

为什么?

【问题讨论】:

  • 我确定,你可以试试it
  • 是的,我意识到sum 来自Data.Foldable

标签: haskell functor foldable


【解决方案1】:

我认为这里可能有两个令人困惑的地方。

首先,最明显的是,sum 适用于 Foldable 事物,而不仅仅是列表。因此:

sum (Just 3) == 3

第二个是你正在使用的仿函数实例。由于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  

如果我们将fmap 替换为.,事情就会开始变得更有意义。

Prelude> (.) sum Just 3
3

Prelude> (sum . Just) 3
3

与此相同

sum (Just 3)

【讨论】:

  • 非常感谢。我是哈斯克尔新手。我没有学过读者实例,但我认为你是对的。我稍后会检查它。
  • 不客气。在大多数情况下,这个实例通常显示为((->) r),当它出现在某个地方时,很容易错过正在发生的事情,仅仅是因为函数感觉它们应该以某种方式表现特殊,但在 Haskell 中,它是一个和其他所有类型一样的类型,所以它比其他语言更加一致。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-21
  • 2017-01-27
  • 1970-01-01
  • 2018-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多