为什么minimum (1, 2)
在Haskell中是2?
我的测试结果是GHCi,
GHCi, version 8.2.1: http://www.haskell.org/ghc/ :? for help
Prelude> minimum (1, 2)
2
不应该返回1吗?
答案 0 :(得分:7)
minimum
的类型是
(Ord a, Foldable t) => t a -> a
对的Foldable
实例仅指对该对的第二个元素,您可以使用toList
查看:
toList (1,2)
> [2]
该集合中的最小元素为2
。
答案 1 :(得分:3)
这种行为的原因有两个:
minimum
或length
等函数(这些是catamorphisms,即将容器结构简化为单个值的函数)只是在列表上运行,但在一般Foldable
个实例上。这非常有用,例如,您可以直接计算数组,map或trie的最小值,而无需先将其转换为列表。 (在FTP之前,你的表达式只是一个类型错误,因为参数不是列表而是元组。)元组是仿函数,具体来说,它们是第二个参数中的仿函数。这允许做像
这样的事情Prelude> fmap (+1) <$> [("Bla",2), ("blub",3)]
[("Bla",3),("blub",4)]
这是第二个论点,因为(a,b)
实际上是((,) a) b
的语法糖,即我们在这里处理((,)a)
仿函数。这是唯一可能的方式你可以创建一个Haskell元组仿函数实例!恕我直言,虽然†,但实际上这个实例并不是一个很好的功能,因为元组在元素之间应该是对称。好吧,Haskell元组不是对称的,它们是“包含一个多态元素的容器”,即第二个。
这本身并不会太糟糕,但是元组也有一个Foldable
实例:一旦你确定一个元组是第二个元素的容器,那么自然也想在其上运行catamorphisms。它们不是非常令人兴奋的catamorphisms,只在一个元素上工作,特别是它真的令人困惑,即使第一个元素具有相同的类型,catamorphism只是忽略它。但是哦,好吧,我们在这里。
† 编写上述内容的正确方法是IMO second (+1) <$> [("Bla",2), ("blub",3)]
,使用second
from Control.Arrow
,相当于元组上的fmap
,但避免了这两个要素之间的混淆。 (此外,它更通用,但不会对大多数应用程序产生影响:它可以与一般的箭头一起使用,而不仅仅与函数一起使用。)
答案 2 :(得分:1)