我正在尝试使用Maybe& amp从列表中获取最大数量只是和递归。我已经找到了递归部分,但无法理解使用
的正确语法Haskell代码 ..
Max :: [Int] -> Maybe Int
Max [_] = []
Max (x:xs)
| x > (Max xs) = Just x
| otherwise = Max xs
输入
Max [1,2,78]
Max [-99,-12,-37]
编译错误消息
*Main> :l max.hs
[1 of 1] Compiling Main ( max.hs, interpreted )
max.hs:2:14: error:
* Couldn't match expected type `Maybe Int' with actual type `[a0]'
* In the expression: []
In an equation for `Max': Max [_] = []
|
2 | Max [_] = []
| ^^
max.hs:4:16: error:
* Couldn't match expected type `Int' with actual type `Maybe Int'
* In the second argument of `(>)', namely `(Max xs)'
In the expression: x > (Max xs)
In a stmt of a pattern guard for
an equation for `Max':
x > (Max xs)
|
4 | | x > (Max xs) = Just x
| ^^^^^^^^^
Failed, no modules loaded.
答案 0 :(得分:2)
语法isn' 重要。更重要的是要了解
为什么你想要回复Maybe Int
而不是Int
第一名。
整数是完全有序的集合,但没有最小
(小于或等于任何其他元素的元素)。因此,
如果返回类型只是Int
,那么人们就不知道要为空列表返回什么。
从概念上讲,人们希望返回类似“负面”的东西
无穷大",但这不是一个合适的整数。
相反,我们可以做以下事情。我们定义一个新的完全有序的集合
Maybe Int
,其中
Just n
对应普通整数n
Nothing
对应于"负无穷大" 在比较Just n
和Just m
时,我们只是比较n
和m
。
将Just n
与Nothing
进行比较时,Just n
应始终如此
大于Nothing
。也就是说,Nothing
变为人为添加
"负无穷大" - 最小元素。
现在,由于list数据类型有两个构造函数(空列表和
头部元素cons
编辑到尾部),我们需要两种情况:
x
,请将Just x
与尾部的最大值进行比较。比较时,我们必须区分尾部最大的情况
可以是Nothing
或Just m
。
总而言之,我们获得了类似的东西:
findMax :: [Int] -> Maybe Int
findMax [] = Nothing
findMax (x:xs) =
case (findMax xs) of
Nothing -> Just x
Just m -> if x > m then Just x else Just m
main = print $ show $ findMax [22, 23, 52, 21, 33, 71, 15, 18, 34]
请注意,我将Max
重命名为findMax
,因为函数名称应以小写字母开头。
答案 1 :(得分:1)
您的代码中似乎有几个问题需要解决:
(1)函数名通常在Haskell中以小写开头
(2)考虑到(1),我们可能不想覆盖Prelude中的max
(3)第一行与列表中的内容匹配:Max [_] = []
表示如果_
是最大的,我们会得到错误的答案:)
(4)(3)中的行返回[]
,这不是Maybe类型。返回Nothing
而不是
(5)我们需要一个"最低"要匹配的号码。安德烈的回答提供了一个很好的概念选择。我已经为更加肮脏而又古怪的-1/0
寻找了一个非常低的数字。
希望这有帮助!
import Data.Maybe
myMax :: [Int] -> Maybe Int
myMax [] = Nothing
myMax (x:xs)
-- we need fromMaybe here because we can't `>` with Nothing
| x > fromMaybe (floor(-1/0)) (myMax xs) = Just x
| otherwise = myMax xs
main = print(myMax [1,2,78])