Haskell-获取第n个元素,不带“!!”&引用;

Haskell-获取第n个元素,不带“!!”&引用;,haskell,Haskell,嗨,我需要得到列表的第n个元素,但不使用!!操作人员我是haskell的新手,如果您能回答得更详细,而不是一行代码,我将不胜感激。这就是我目前正在尝试的: nthel:: Int -> [Int] -> Int nthel n xs = 0 let xsxs = take n xs nthel n xs = last xsxs 但我得到:解析错误(可能是不正确的缩进) 提前谢谢你 这里有很多东西有点不对劲 nthel :: Int -> [Int] -> Int 从技

嗨,我需要得到列表的第n个元素,但不使用!!操作人员我是haskell的新手,如果您能回答得更详细,而不是一行代码,我将不胜感激。这就是我目前正在尝试的:

nthel:: Int -> [Int] -> Int
nthel n xs = 0
let xsxs = take n xs
nthel n xs = last xsxs
但我得到:解析错误(可能是不正确的缩进)


提前谢谢你

这里有很多东西有点不对劲

nthel :: Int -> [Int] -> Int
从技术上讲是正确的,真的是我们想要的

nthel :: Int -> [a] -> a
所以我们可以在任何东西的列表上使用它(可选)

您刚才所说的是“无论您给予
nthel什么
return0”。这显然是错误的

let xsxs = ...
这是不合法的,哈斯克尔<代码>让。。。在…中是一个表达式,不能用于顶级


从那以后,我真的不知道该怎么做

也许这会帮助你走上正轨

nthelem n [] = <???> -- error case, empty list
nthelem 0 xs = head xs
nthelem n xs = <???> -- recursive case
n元素n[]=--错误案例,空列表
n元素0 x=头部x
n元素n xs=--递归情况
试着在
中填入您的最佳猜测,我很乐意从中提供帮助

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

这就把我们的上面改成了

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
n元素n[]=--错误案例,空列表
n元素0(x:xs)=x——将x绑定到第一个元素,将x绑定到列表的其余部分
n元素n(x:xs)=--递归情况

这样做很方便,因为它不需要使用显式的
head
tail
s。我想你的意思是:

nthel n xs = last xsxs
  where xsxs = take n xs
。。。您可以将其简化为:

nthel n xs = last (take n xs)

我认为你应该尽可能避免使用
last
——列表是从“前端”开始使用的,而不是从后端。您想要的是去掉前n个元素,然后得到剩余列表的头(当然,如果剩余的是空的,您会得到一个错误)。您可以非常直接地表示为:

nthel n xs = head (drop n xs)
或更短:

nthel n = head . drop n
或者有点疯狂:

nthel = (head .) . drop

正如你们所知,这个列表并没有自然地编入索引,但可以使用一个通用的技巧来克服它

试试ghci,
zip[0..]“你好”
,关于
zip[0,1,2]“你好”
zip[0..10]“你好”

从这个观察开始,我们现在可以很容易地获得一种为列表编制索引的方法。
此外,这是懒惰的一个很好的例子,是你学习过程的一个很好的提示

在此基础上,利用模式匹配技术,提出了一种有效的算法

  • 边界案例的管理(空列表、负索引)
  • 使用拉链将列表替换为索引版本
  • 调用助手函数设计递归处理索引列表 现在对于helper函数,列表不能为空,然后我们可以简单地进行模式匹配

    • 如果我们的指数等于n,我们就赢了
    • 否则,如果下一个元素为空,则结束
    • 否则,使用下一个元素调用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 
    
    nth::Int->[a]->可能是
    n n x
    |空xs | | n<0=无
    |否则=辅助对象n zs
    哪里
    zs=zip[0..]xs
    助手n((i,c):zs)
    |i=n=c
    |空zs=无
    |否则=辅助对象n zs
    
    让xsxs=take n xs
    -它应该做什么?“从那以后,我不确定应该做什么。”我试图将列表剪切到第n个元素,然后再获取最后一个元素(即第n个元素)。我发现这将是不带第n个元素的最简单方法!!。如果你知道一些简单的东西,请随意分享。无论如何,谢谢你的回复!我做到了,这就是文章的全部内容,这就是我一直在努力解决的问题——如何在文章中同时使用take和last。很抱歉问了这么多愚蠢的问题,但我要做haskell几个小时。你不需要
    take
    last
    ,你可以使用递归和
    head
    tail
    来完成。不要担心问问题,哈斯克尔很难回答first@PhilipJF他在“几个小时前”开始了haskell我不会教他一些他不懂的东西。他甚至不懂函数的语法,你想让我用模式匹配吗?加上它使空白完全琐碎!非常感谢。你们两个,给自己投票吧,因为我的评分太低了,不能自己投票。:)只有当列表的长度至少与所需索引一样长时,take才能返回n或列表的长度,因此“abc”的第15个元素返回“c”,而不是什么都没有。
    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