Haskell:如何使用Maybe安全地实现max?

问题描述 投票:0回答:1

我想实现一个递归安全max函数,如果提供了一个空列表,则返回Nothing;如果找到最大值,则返回Just a

一种幼稚的方法(如果提供了一个空列表,它只会返回零):

max' :: [Int] -> Int
max' [] = 0
max' (x:xs) | x < max' xs = max' xs
            | otherwise = x

现在使用Prelude Maybe数据类型:

safeMax :: (Ord a) => [a] -> Maybe a
safeMax [] = Nothing
safeMax [x] = x
safeMax (x:y:xs) | x = safeMax (y:xs)
               | otherwise = Just x

我收到一条消息,它无法构造无限数据类型a ~ Maybe a。这是什么问题?

完整的错误消息是这样:

safemax.hs:33:15: error:
    • Occurs check: cannot construct the infinite type: a ~ Maybe a
    • In the expression: x
      In an equation for ‘safeMax’: safeMax [x] = x
    • Relevant bindings include
        x :: a (bound at safemax.hs:33:10)
        safeMax :: [a] -> Maybe a (bound at safemax.hs:32:1)
   |
33 | safeMax [x] = x

解决方案:使用Just x并使用x < y

safeMax :: (Ord a) => [a] -> Maybe a
safeMax [] = Nothing
safeMax [x] = Just x
safeMax (x:y:xs) | x < y = safeMax (y:xs)
               | x > y = safeMax (x:xs)
               | otherwise = Just x
haskell
1个回答
1
投票

我相信问题出在x < safeMax xs。在这里,您尝试使用(<)aMaybe a进行比较。在进行此比较之前,您需要从safeMax xs解开返回值。

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