[英]Haskell - MinMax using foldr
我正在寻找一个Haskell函数,该函数将列表作为参数并返回一个元组(min,max),其中min是列表的最小值,而max是最大值。
我已经有这个了:
maxMinFold :: Ord a => [a] -> (a, a)
maxMinFold list = foldr (\x (tailMin, tailMax) -> (min x tailMin) (max x tailMax)) -- missing part
您能帮我增加什么到缺少的部分吗? (或告诉我我在做什么错)
非常感谢
您拿起头部并将其用作拳头的最小值和最大值,然后在尾巴上折叠。
maxMinFold :: Ord a => [a] -> (a, a)
maxMinFold (x:xs) = foldr (\x (tailMin, tailMax) -> (min x tailMin, max x tailMax)) (x,x) xs
关于您的答案,您的折叠功能没有返回正确的类型。
注意
foldr :: (a -> b **-> b**) -> b -> [a] -> b
特别是您需要返回b
,这是您的情况下的元组
由于您始终必须遍历整个列表以找到最小值和最大值,因此这里是foldl
的解决方案:
maxMinList :: Ord a => [a] -> (a,a)
maxMinList (x:xs) = foldl (\(l,h) y -> (min l y, max h y)) (x,x) xs
为了有效地使用文件foldr
,
data NEList a = NEList a [a]
-- deriving (Eq, Ord, Show, Read, Functor, Foldable, Traversable)
minMax :: Ord a => NEList -> (a, a)
minMax (NEList x0 xs) = foldr go (,) xs x0 x0 where
go x r mn mx
| x < mn = r x mx
| mx < x = r mn x
| otherwise = r mn mx
另一种类似的方法:
minMaxM :: Ord a => [a] -> Maybe (a, a)
minMaxM xs = foldr go id xs Nothing where
go x r Nothing = r (Just (x, x))
go x r mnmx@(Just (mn, mx))
| x < mn = r (Just (x, mx))
| mx < x = r (Just (mn, x))
| otherwise = r mnmx
如果在空白列表的情况下minMax
函数返回Nothing
,那将是很好的。 这是执行此操作的版本。
import Control.Arrow
import Data.Maybe
import Data.Foldable
minMax :: (Ord a) => [a] -> Maybe (a,a)
minMax = foldl' (flip $ \ x -> Just . maybe (x,x) (min x *** max x)) Nothing
这使用foldl'
而不是foldr
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.