您好我需要获取列表的第n个元素但不使用!!运营商。我对haskell非常陌生,所以如果您能够更详细地回答而不仅仅是一行代码,我将不胜感激。这就是我现在正在尝试的事情:
nthel:: Int -> [Int] -> Int
nthel n xs = 0
let xsxs = take n xs
nthel n xs = last xsxs
但我得到:解析错误(可能是错误的缩进)
提前谢谢!
答案 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
这样做非常方便,因为它无需使用明确的head
和tail
。
答案 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"
是什么?
从这个观察开始,我们现在可以轻松获得索引列表的方法
此外,还可以很好地说明懒惰的使用,这是您学习过程的一个很好的暗示。
然后基于此并使用模式匹配,我们可以提供有效的算法。
现在对于辅助函数,列表不能为空,那么我们可以天真地模式匹配,并且,
另外请注意,由于我们的函数可能失败(空列表...),使用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