错误“(Num [t]) 没有实例”在 Collatz 函数中
我是 Haskell 和一般编程的新手。我正在尝试定义一个函数,该函数从 n 生成 Collatz 数字序列。我有:
collatz n = (collatz' n) : 1
where collatz' n = (takeWhile (>1) (collatz'' n))
where collatz'' n = n : collatz'' (collatz''' n)
where collatz''' 1 = 1
collatz''' n = if (even n) then (div n 2) else ((3*2)+1)
当我在 GHCi 中运行它时,我收到错误:
No instance for (Num [t])
arising from the literal `2' at <interactive>:1:7
Possible fix: add an instance declaration for (Num [t])
我不知道这意味着什么。问题似乎是将“1”附加到列表中。出现这个问题是因为
collatz' n = (takeWhile (>0) (collatz'' n))
在正确的 Collatz 序列之后生成了无限的“1”序列;然而,
collatz' n = (takeWhile (>1) (collatz'' n))
从n生成除“1”之外的所有 Collatz 数。我做错了什么?
I am new to Haskell, and programming in general. I am trying to define a function which generates the sequence of Collatz numbers from n. I have:
collatz n = (collatz' n) : 1
where collatz' n = (takeWhile (>1) (collatz'' n))
where collatz'' n = n : collatz'' (collatz''' n)
where collatz''' 1 = 1
collatz''' n = if (even n) then (div n 2) else ((3*2)+1)
When I run this in GHCi, I get the error:
No instance for (Num [t])
arising from the literal `2' at <interactive>:1:7
Possible fix: add an instance declaration for (Num [t])
I don't know what this means. The problem seems to be appending "1" to the list. This problem emerges because
collatz' n = (takeWhile (>0) (collatz'' n))
generates an infinite sequence of "1"s following the correct Collatz sequence; however,
collatz' n = (takeWhile (>1) (collatz'' n))
generates all Collatz numbers from n except "1". What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
<代码>(:) :: a -> [一]-> [a]
您的第一行
collatz n = (collatz' n) : 1
强制1
变为[a]
。我猜你想要类似
(collatz' n) ++ [1]
并且
if (even n) then (div n 2) else ((3*2)+1)
中出现错误,应该是((3*n)+1
或类似的东西,否则你有collatz''' 7 = 7
(:) :: a -> [a] -> [a]
Your first line
collatz n = (collatz' n) : 1
forces1
to become[a]
.I guess you wanted something like
(collatz' n) ++ [1]
And you have error in
if (even n) then (div n 2) else ((3*2)+1)
there should be((3*n)+1
or something like that else you havecollatz''' 7 = 7
ony 的答案是正确的,但由于您是 Haskell 新手,也许这是一个更清晰的解释。
:
运算符在列表中添加一个值,因此执行somelist : 7
是无效的,因为它试图ap 将一个值挂起到列表中。这就是(collatz' n) : 1
无法编译的原因,因为(collatz' n)
的类型是数字列表。尝试将
: 1
替换为++ [1]
。ony's answer is correct, but since you're new to Haskell, maybe this is a clearer explanation. The
:
operator prepends a value to a list, so doingsomelist : 7
is invalid since that's trying to append a value to a list. That's why(collatz' n) : 1
doesn't compile, since the type of(collatz' n)
is a list of numbers.Try replacing the
: 1
with++ [1]
.解决该问题的另一种方法可能是使用 Data.Sequence 结构而不是列表。序列允许您“snoc”一个值(将值放在序列的后面)以及更常见的“cons”(将其放在序列的前面)。
您的另一个解决方案可能是使用
span
来制作您自己的“takeUntil”函数。让我解释一下:对于任何
p
函数和span p xs
都会为您提供与(takeWhile p xs, dropWhile p xs)
相同的答案您将使用的 >xs 列表,与splitAt n xs
与(take n xs, drop n xs)
相同。无论如何,您可以使用
span
来制作自己的“takeUntil”函数:当您使用
collatz n = (collatz' n) 时,这就是您正在寻找的形式: 1< /代码> 形式。
我希望这有帮助。
Another way to go at the problem may be for you to use a Data.Sequence structure instead of a list. Sequences allow you to "snoc" a value (put a value on the back of a sequence) as well as the more usual "cons" (put it on the front of the sequence).
Another solution for you may be to use
span
to make your own "takeUntil" function.Let me explain:
span p xs
gives you the same answer as(takeWhile p xs, dropWhile p xs)
for whicheverp
function andxs
list you'd use, the same way thatsplitAt n xs
is the same as(take n xs, drop n xs)
.Anyway, you can use
span
to make your own "takeUntil" function:This is the form that you were looking for, when you used the
collatz n = (collatz' n) : 1
form.I hope this helps.