错误“(Num [t]) 没有实例”在 Collat​​z 函数中

发布于 2024-09-07 13:33:29 字数 847 浏览 7 评论 0原文

我是 Haskell 和一般编程的新手。我正在尝试定义一个函数,该函数从 n 生成 Collat​​z 数字序列。我有:

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))

在正确的 Collat​​z 序列之后生成了无限的“1”序列;然而,

collatz' n = (takeWhile (>1) (collatz'' n))

n生成除“1”之外的所有 Collat​​z 数。我做错了什么?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

弥繁 2024-09-14 13:33:29

<代码>(:) :: a -> [一]-> [a]
您的第一行 collat​​z n = (collat​​z' n) : 1 强制 1 变为 [a]
我猜你想要类似 (collat​​z' n) ++ [1]
并且 if (even n) then (div n 2) else ((3*2)+1) 中出现错误,应该是 ((3*n)+1 或类似的东西,否则你有 collat​​z''' 7 = 7

(:) :: a -> [a] -> [a]
Your first line collatz n = (collatz' n) : 1 forces 1 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 have collatz''' 7 = 7

筑梦 2024-09-14 13:33:29

ony 的答案是正确的,但由于您是 Haskell 新手,也许这是一个更清晰的解释。 : 运算符在列表中添加一个值,因此执行 somelist : 7 是无效的,因为它试图ap 将一个值挂起到列表中。这就是 (collat​​z' n) : 1 无法编译的原因,因为 (collat​​z' 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 doing somelist : 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].

桃扇骨 2024-09-14 13:33:29

解决该问题的另一种方法可能是使用 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”函数:

takeUntil p xs = taken ++ take 1 dropped where
                 (taken, dropped) = span p xs

当您使用 collat​​z n = (collat​​z' 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 whichever p function and xs list you'd use, the same way that splitAt n xs is the same as (take n xs, drop n xs).

Anyway, you can use span to make your own "takeUntil" function:

takeUntil p xs = taken ++ take 1 dropped where
                 (taken, dropped) = span p xs

This is the form that you were looking for, when you used the collatz n = (collatz' n) : 1 form.

I hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文