Haskell - 没有“!!”得到第n个元素

时间:2013-04-12 21:16:45

标签: haskell

您好我需要获取列表的第n个元素但不使用!!运营商。我对haskell非常陌生,所以如果您能够更详细地回答而不仅仅是一行代码,我将不胜感激。这就是我现在正在尝试的事情:

nthel:: Int -> [Int] -> Int
nthel n xs = 0
let xsxs = take n xs
nthel n xs = last xsxs

但我得到:解析错误(可能是错误的缩进)

提前谢谢!

4 个答案:

答案 0 :(得分:12)

这里有很多东西,

nthel :: Int -> [Int] -> Int

在技术上是正确的,我们真的想要

nthel :: Int -> [a] -> a

所以我们可以在任何事物的列表上使用它(可选)

nthel n xs = 0

你刚才说的是“无论你给nthel返回0”。这显然是错误的。

let xsxs = ...

这不是合法的哈克尔。 let ... in ...是一个表达式,它不能用于表达。

从那时起,我不确定应该做什么。

也许这会帮助你走上正确的轨道

nthelem n [] = <???> -- error case, empty list
nthelem 0 xs = head xs
nthelem n xs = <???> -- recursive case

尝试用最好的猜测填写<???>,我很乐意从那里获得帮助。

或者,您可以使用Haskell的“模式匹配”语法。我将解释如何使用列表here执行此操作。

这将我们的上述内容改为

nthelem n [] = <???> -- error case, empty list
nthelem 0 (x:xs) = x --bind x to the first element, xs to the rest of the list
nthelem n (x:xs) = <???> -- recursive case

这样做非常方便,因为它无需使用明确的headtail

答案 1 :(得分:8)

我认为你的意思是:

nthel n xs = last xsxs
  where xsxs = take n xs

...您可以简化为:

nthel n xs = last (take n xs)

答案 2 :(得分:1)

我认为你应该尽可能避免使用last - 列表是从“前端”使用的,而不是从后面使用的。你想要的是摆脱前n个元素,然后得到剩余列表的头部(当然,如果其余的是空的,你会得到一个错误)。你可以直接表达:

nthel n xs = head (drop n xs)

或更短:

nthel n = head . drop n

或者有点疯狂:

nthel = (head .) . drop

答案 3 :(得分:0)

如您所知,列表不是自然索引的,但可以使用常见提示来克服。

尝试使用ghci,zip [0..] "hello"zip [0,1,2] "hello"zip [0..10] "hello"是什么? 从这个观察开始,我们现在可以轻松获得索引列表的方法 此外,还可以很好地说明懒惰的使用,这是您学习过程的一个很好的暗示。

然后基于此并使用模式匹配,我们可以提供有效的算法。

  1. 管理边界案例(空列表,负索引)。
  2. 使用zipper通过索引版本替换列表。
  3. 调用辅助函数设计以递归方式处理索引列表。
  4. 现在对于辅助函数,列表不能为空,那么我们可以天真地模式匹配,并且,

    • 如果我们的指数等于n我们有一个胜利者
    • 否则,如果我们的下一个元素为空,那么它就结束了
    • else,使用下一个元素调用helper函数。

    另外请注意,由于我们的函数可能失败(空列表...),使用Maybe类型包装我们的结果可能是件好事。

    把这一切放在一起我们结束了。

    nth :: Int -> [a] -> Maybe a
    nth n xs 
        | null xs || n < 0 = Nothing
        | otherwise        = helper n zs 
          where 
            zs = zip [0..] xs 
            helper n ((i,c):zs) 
                | i == n    = Just c
                | null zs   = Nothing
                | otherwise = helper n zs