Haskell';s";“尾巴”-功能有哪些?

Haskell';s";“尾巴”-功能有哪些?,haskell,Haskell,当我在读哈斯克尔的教程时,我在想Haskell的tail函数的时间复杂度是多少(为什么)?(我在任何文档中都找不到答案) 我猜对于大小为n的列表,tail函数将是O(n),即只是将尾部复制到一个新列表并返回该列表。但是再一次,我对Haskell的底层架构知之甚少(我对该语言不太熟悉) 当然,我可以计时。但我还不知道如何在Haskell中计算时间,我还想了解Haskell是如何处理这个问题的,以证明它是O(n)/O(1)或其他什么 提前感谢:)简短回答:如果列表已经构建到该节点,O(1) Hask

当我在读哈斯克尔的教程时,我在想Haskell的
tail
函数的时间复杂度是多少(为什么)?
(我在任何文档中都找不到答案)

我猜对于大小为n的列表,
tail
函数将是O(n),即只是将尾部复制到一个新列表并返回该列表。但是再一次,我对Haskell的底层架构知之甚少(我对该语言不太熟悉)

当然,我可以计时。但我还不知道如何在Haskell中计算时间,我还想了解Haskell是如何处理这个问题的,以证明它是O(n)/O(1)或其他什么


提前感谢:)

简短回答:如果列表已经构建到该节点,O(1)

Haskell中的列表是链接列表。其定义如下:

data [a] = [] | a : [a]
这意味着要么是空列表,要么是
a:[a]
构造。因此,一个节点有一个
(一个
a
)表示
a
类型的对象,一个
表示一个列表
[a]
(可以是空列表,也可以是另一个节点)

尾部
的源代码定义为:

data [a] = [] | a : [a]
它在O(1)中运行,因为我们只需跟随指向该节点“尾部”的指针


但是请注意,Haskell工作很懒。并不是因为我们得到了一个类型为
[a]
的对象,所以我们有了一个物化列表:通常Haskell必须首先计算表达式树,因为它已经交给了给定的节点。这可能导致评估复杂且耗时的算法。因此,它取决于所给的表达式树,该语言没有指定。但在GHC(最常用的实现)中,它是O(1)。尾部不需要复制——在原始列表和仅使用列表尾部的用户之间共享是安全的——因为Haskell中的所有内容都是不可变的


挑战问题:为什么保留列表中除最后一个元素外的所有元素的
init
,都在O(n)中运行?为什么上面的共享论点不适用于这里?

我不知道它实际上是一个链表!谢谢你提供了非常有用的信息:)被接受的答案与这个答案相结合,是一个健康的答案!关于挑战问题;如果我可以假设列表是一个单链接列表(如Williems答案中所述),那么它应该是O(n),因为如果不删除指向最后一个元素的“指针”(不可能),或者不将值复制到不包含最后一个元素的新链接列表中,就不可能有没有最后一个元素的列表。这是一个正确的推理方式吗?@ SimonSirak,但是考虑<代码>数据nList a= nList([a],Int)< /C> >代码< int /c> >是列表的长度。code>init
然后或多或少地变成
秒(减去1)