我正在尝试将使用foldr函数的最大函数转换为也包含may类型的函数。它最初是:
maximum' :: (Ord a) => [a] -> a
maximum' = foldr1 (\x acc -> if x > acc then x else acc)
它与套装完美配合,但不适用于空套装。我想将它转换为使用类型而不是。
我的思维过程是:
mymax :: (Ord a) => [Maybe a] -> Maybe a
mymax = foldr (\(Just x) (Just b) -> if ((Just x) > (Just b)) then (Just x) else (Just b)) Nothing
它编译时没有错误,并且在我给它空集时起作用。但是,当我给它一个带有数字的集合时,它就不再起作用了!有人可以指出我正确的方向,我如何从它的功能中获得最大的可能性列表?
我真的想在我的解决方案中使用foldr函数....
我现在尝试过:
mymax :: (Ord a) => [a] -> Maybe a
mymax = foldr (\x b -> if x > b then (Just x) else (Just b)) Nothing
但它不会编译:
Couldn't match expected type `Maybe b -> Maybe a'
with actual type `Maybe a0'
In the return type of a call of `Just'
Probable cause: `Just' is applied to too many arguments
In the expression: (Just x)
In the expression: if x > b then (Just x) else (Just b)
Failed, modules loaded: none.
答案 0 :(得分:4)
我认为您确实希望mymax
拥有(Ord a) => [a] -> Maybe a
类型。这是一个使用模式匹配和原始maximum'
函数的潜在实现:
mymax :: (Ord a) => [a] -> Maybe a
mymax [] = Nothing
mymax xs = Just (maximum' xs)
此外,Learn You A Haskell是一个很好的资源,如果你还没有遇到它!
答案 1 :(得分:4)
如果您想在单个foldr
中执行此操作,我们可以利用Ord a => Ord (Maybe a)
这一事实,即a
上的任何排序都可以扩展为Maybe a
上的排序1}}。
对于所有Just x > Nothing
,我们还有x :: Ord a => a
。
mymax :: (Ord a) => [a] -> Maybe a
mymax = foldr (\x b -> let x' = Just x in if x' > b then x' else b) Nothing
-- equivalently
mymax = foldr (\x b -> let x' = Just x in max x' b) Nothing
mymax = foldr (\x' b -> max x' b) Nothing . map (\x -> Just x)
mymax = foldr max Nothing . map Just
如果我们想做最小化,我们必须采用不同的方式,因为Nothing
是类型Ord a => Maybe a
的下限,这意味着foldr min Nothing . map Just == const Nothing
,没用。
mymin :: (Ord a) => [a] -> Maybe a
mymin = foldr (\x b -> case b of
Nothing -> Just x
Just y -> Just (min x y)
) Nothing
-- which is equivalent to
mymin = foldr (\x b -> Just $ case b of
Nothing -> x
Just y -> min x y
) Nothing
mymin = foldr (\x b -> Just $ maybe x (min x) b) Nothing
mymin = foldr (\x -> Just . maybe x (min x)) Nothing
老实说,我认为模式匹配使解决方案更加清晰
mymax [] = Nothing
mymax (a:as) = Just $ foldr max a as
mymin [] = Nothing
mymin (a:as) = Just $ foldr min a as