【问题标题】:Error "No instance for (Num [t])" in Collatz functionCollat​​z 函数中出现错误“No instance for (Num [t])”
【发布时间】:2010-07-02 06:39:32
【问题描述】:

我是 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 中生成所有 Collat​​z 数,“1”除外。我做错了什么?

【问题讨论】:

    标签: haskell list collatz


    【解决方案1】:

    (:) :: a -&gt; [a] -&gt; [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

    【讨论】:

    • 谢谢:这是有道理的,并且为我澄清了 (:)。
    【解决方案2】:

    ony 的答案是正确的,但由于您是 Haskell 的新手,也许这是一个更清晰的解释。 : 运算符 pre 将值挂起到列表中,因此 somelist : 7 是无效的,因为它试图 ap 将值挂到列表中。这就是(collatz' n) : 1 无法编译的原因,因为(collatz' n) 的类型是数字列表。

    尝试将: 1 替换为++ [1]

    【讨论】:

    • (collatz' n) : [] 很好。它将产生类似[[a]] 的东西(实际上原始示例已编译,但第一个参数a 没有类型绑定可以满足类限制:collatz :: (Integral a, Num [[a]]) =&gt; a -&gt; [[a]])。问题是任何数字(即1)只能编译成满足Num a类的数据值。
    • 也谢谢:我之前重写了整个函数以强制 (:) 工作。你为我节省了很多时间!
    【解决方案3】:

    解决问题的另一种方法可能是使用 Data.Sequence 结构而不是列表。序列允许您“snoc”一个值(将一个值放在序列的后面)以及更常见的“缺点”(将它放在序列的前面)。

    您的另一种解决方案可能是使用span 制作您自己的“takeUntil”函数。

    让我解释一下:span p xs 为您提供与(takeWhile p xs, dropWhile p xs) 相同的答案,无论您使用哪个p 函数和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
    

    这是您在使用 collatz n = (collatz' n) : 1 表单时要查找的表单。

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2017-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-06
      • 2013-10-17
      • 2018-07-10
      • 2018-01-18
      相关资源
      最近更新 更多