在代码的不同部分移动Data.List maximum
函数时,我很难理解Haskell的错误。我正在使用一些内置函数来查找任意整数列表的模式。例如,为mode
赋予列表list = [1,2,3,4,5,5,6,6,5,5,4,4,3,4,5,6,7,8,6,5,3,2,5]
时,它应返回5
。
当我将内置maximum
函数放入mode
函数内部时,如下所示:
mode l = case l of
[] -> []
(x : xs) ->
let x = map length (group (sort l))
y = map head (group (sort l))
in snd (maximum (zip x y)) --<-----<-----<-- This Line
我在mode
中使用命令> list
在以上mode list
上运行ghci
,它给了我以下错误输出:
<interactive>:2:7: error:
* Couldn't match type `Integer' with `[a]'
Expected type: [[a]]
Actual type: [Integer]
* In the first argument of mode', namely `list'
In the expression: mode' list
In an equation for `it': it = mode' list
* Relevant bindings include it :: [a] (bound at <interactive>:2:1)
但是,当我将mode
函数分解为mode
和mode'
(其中mode'
发挥最大作用)时,像这样:< / p>
mode' f l = snd (maximum (f l)) --<-----<-----<-- Now Here
mode l = case l of
[] -> []
(x : xs) ->
let x = map length (group (sort l))
y = map head (group (sort l))
in zip x y
并且我在上述mode
上运行list
,在mode' mode list
中使用> ghci
,我得到了5
的预期输出,没有错误。>
谁能解释为什么会这样?
答案 0 :(得分:3)
仔细研究case
中的mode
语句:
在您的工作示例中:
mode l = case l of
[] -> []
(x : xs) -> let ... in zip x y
mode
的返回类型是一个列表。在损坏的版本中:
mode l = case l of
[] -> []
(x : xs) -> let ... in snd (maximum (zip x y))
第一个分支中的返回类型是一个列表,但是在第二个分支中,它的返回类型是Integer
(与zip x y :: [(Integer, a)]
相同)。那是类型错误。
在工作情况下,mode
的另一个分支返回一个列表,因此类型有效:mode :: (Num a, Ord b) => [b] -> [(a, b)]
,并且mode'
也进行类型检查。
错误消息Couldn't match type 'Integer' with '[a]'
表示该函数需要一个列表[a]
,但得到了一个Integer
:您的列表包含整数,因此您可以判断该函数正在使用该参数改为列表列表:则类型有效(mode :: Ord a => [[a]] -> [a]
)。
答案 1 :(得分:1)
说mode' mode
时,可以内联为:
mode l = case l of
[] -> snd (maximum [])
(x : xs) ->
let x = map length (group (sort l))
y = map head (group (sort l))
in snd (maximum (zip x y))
请注意,这与原始文档不同,因为无论mode'
是否为空,都会应用list
,而原始文档仅在非空情况下应用。{p>
还要注意,snd (maximum [])
进行类型检查,但会引发运行时错误Exception: Prelude.maximum: empty list
。这意味着您仍然需要回答以下问题:空列表该怎么办?
我认为答案必须是空列表没有模式,因此您要返回的内容必须是Maybe
。这意味着您可以使用以下定义:
mode l = case l of
[] -> Nothing
_ ->
let x = map length (group (sort l))
y = map head (group (sort l))
in Just (snd (maximum (zip x y)))
(请注意,为了避免在您再次让(x : xs)
定义_
时造成混淆,我将x
替换为未使用的var mysort = { comments: 1 };
Post.find( {} )
.sort(mysort)
.exec( (err, posts)=>{
if(err) {
return res.status(400).json({
ok: false,
message: 'Error loading posts',
});
}
return res.status(200).json({
ok: true,
posts: posts
});
});
模式。)