1

我正在尝试将使用 foldr 函数的最大函数转换为也包含可能类型的函数。原来是:

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.
4

2 回答 2

4

如果你想在一个单一的foldr,我们可以利用这样一个事实Ord a => Ord (Maybe a),即任何排序a都可以扩展到一个排序Maybe a

我们也Just x > Nothingx :: 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是 type 的下限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
于 2013-09-18T02:12:17.613 回答
4

我认为您实际上想要mymaxtype (Ord a) => [a] -> Maybe amaximum'这是一个使用模式匹配和您的原始功能的潜在实现:

mymax :: (Ord a) => [a] -> Maybe a
mymax [] = Nothing
mymax xs = Just (maximum' xs)

此外,Learn You A Haskell是一个很好的资源,如果你还没有遇到过的话!

于 2013-09-18T00:58:13.777 回答