为什么在Haskell中最大值(8,1)= 1?

我刚刚开始学习Haskell。据我所知maximum给出了整数列表的最大值。因此,maximum [2,5,7,1]给出7。但是为什么通过给出一个元组输入,max总是给出第二个元素?例如,maximum (8,1)给出1。sum (8,1)product (5,2)minimum (4,5)也会发生同样的事情...都给出了元组的第二个元素。因此,有人可以向初学者解释为什么会发生这种情况吗?

dqsj09021013 回答:为什么在Haskell中最大值(8,1)= 1?

简短答案:对于2元组,Foldable实例(仅)将第二项考虑在内。 maximum函数因此将始终返回2元组的第二项。

因为2元组是Foldable的实例。确实是defined as [src]

instance Foldable ((,) a) where
    foldMap f (_,y) = f y

    foldr f z (_,y) = f y z

maximum本质上是一种文件夹模式。它的实现等效于:

maximum = foldr1 max

foldr1的实现方式为:

foldr1 f = fromMaybe (error "…") . foldr mf Nothing
    where mf x m = Just (case m of
                             Nothing -> x
                             Just y  -> f x y)

这意味着对于2元组,它将实现为:

maximum (_,y) = fromMaybe (error "…") (mf y Nothing)
    where mf x m = Just (case m of
                             Nothing -> x
                             Just y  -> max x y)

因此,在这里我们用mf(作为y参数)调用x,将Nothing称为mcase … of …Nothing匹配并返回x。因此,两个元组的最大值定义为:

maximum (_,y) = fromMaybe (error "…") (Just y)

因此更短:

-- maximum for a (a,b)
maximum (_,y) = y
,

Haskell中的字符串不是像Python中那样的多值容器。相反,它们更接近单个值的容器,例如Maybe aEither b a:具有上下文的值。尽管MaybeEither都可能没有值(Either仅仅提供了比Maybe更多的关于缺少值的信息)的概念,但元组却带有以下内容:有关值本身的信息。

类似(8,1的值不包含两个值81。相反,8是包含1的容器的部分

因此,元组是可折叠的,即使这样做是微不足道的。将类型(a,b)的值减小为b的值仅需返回类型b的值,而不必担心如何处理其他类型b的值,因为没有

>>> maximum (Just 5)
5
>>> minimum (Just 5)
5

>>> maximum (Right 5)
5
>>> minimum (Right 5)
5

>>> maximum (True,5)
5
>>> minimum (True,5)
5

MaybeEither相比,此类函数是带有元组的 total

>>> maximum Nothing
*** Exception: maximum: empty structure
>>> maximum (Left 5)
*** Exception: maximum: empty structure

无论元组包含多少种类型,对于最给定的Foldable实例,除最右边的元组之外的所有元组都将固定。

-- Actual instance for (a,b)
instance Foldable ((,y) = f y
    foldr f z (_,y) = f y z


-- Instance for (a,b,c) if you wanted it
instance Foldable ((,) a b) where
    foldMap f (_,_,y) = f y z
本文链接:https://www.f2er.com/3153073.html

大家都在问