为什么使用Haskell最大值(8,1)= 1?

问题描述 投票:6回答:2

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

haskell max foldable
2个回答
8
投票

简短回答:对于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来调用m。此case … of …Nothing匹配并返回x。因此,一个2元组的最大值定义为:

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

因此更短:

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

1
投票

Haskell中的字符串不是多值容器,就像它们在Python中一样。相反,它们更接近single值的容器,例如Maybe aEither b a:具有上下文的值。 MaybeEither都可能没有值(Either仅提供比Maybe更多的关于缺少值的信息)的概念,而元组则携带有关值本身的信息的上下文。

[(8, 1之类的值)不contain两个值81。相反,8一部分包含1的容器。

因此,元组是可折叠的,即使这样做看起来很琐碎。将类型(a, b)的值减小为b的值仅需返回类型b的值,而不必担心如何处理类型为b的其他值,因为存在are n't 任何。

>>> 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 ((,) a) where foldMap f (_, 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 foldr f z (_, _, y) = f y z

© www.soinside.com 2019 - 2024. All rights reserved.