列表的“最大”功能仅在单独的功能中起作用吗?

时间:2019-01-01 18:59:23

标签: list haskell

在代码的不同部分移动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函数分解为modemode' (其中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的预期输出,没有错误。

谁能解释为什么会这样?

2 个答案:

答案 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 }); }); 模式。)