为什么`最小(1,2)`在Haskell中返回2?

时间:2017-12-09 14:41:58

标签: haskell

为什么minimum (1, 2)在Haskell中是2?

我的测试结果是GHCi,

GHCi, version 8.2.1: http://www.haskell.org/ghc/  :? for help
Prelude> minimum (1, 2)
2

不应该返回1吗?

3 个答案:

答案 0 :(得分:7)

minimum的类型是

 (Ord a, Foldable t) => t a -> a

对的Foldable实例仅指对该对的第二个元素,您可以使用toList查看:

toList (1,2)
> [2]

该集合中的最小元素为2

答案 1 :(得分:3)

这种行为的原因有两个:

  • FTP以来,minimumlength等函数(这些是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)

当您查看documentation时,您会发现最小值可以有各种输入(在参数的类型意义上)。

在您的情况下,您希望将list应用于最小函数以获取最小元素,因此请尝试

minimum [1,2]