我正在尝试使用Haskel实现collatz-list: 这是我的代码:
collatz n
| mod n 2 == 0 = div n 2
| otherwise = 3 * n + 1
collatzList n
| n < 1 = error "Cannot have negative number"
collatzList
| n == 1 = [n]
| otherwise = n:collatzList (collatz n)
我得到的错误信息是: 输入`collatzList'解析错误 [1/1]编译Main(exer.hs,解释) 失败,模块加载:无。
有人能告诉我为什么收到这条消息吗?
答案 0 :(得分:4)
我得到了不同的错误(使用GHC 7.4.1):
> :load "/tmp/C.hs"
[1 of 1] Compiling Main ( /tmp/C.hs, interpreted )
/tmp/C.hs:9:11: Not in scope: `n'
/tmp/C.hs:9:21: Not in scope: `n'
/tmp/C.hs:10:23: Not in scope: `n'
/tmp/C.hs:10:46: Not in scope: `n'
Failed, modules loaded: none.
这是因为您在n
的第二个等式中忘记了collatzList
参数。您可以添加此参数
collatzList n
| n < 1 = error "Cannot have negative number"
collatzList n -- the n was missing here
| n == 1 = [n]
| otherwise = n:collatzList (collatz n)
或者,由于左侧现在是相同的,您可以简单地将它与第一个一起加入:
collatzList n
| n < 1 = error "Cannot have negative number"
| n == 1 = [n]
| otherwise = n:collatzList (collatz n)
答案 1 :(得分:2)
您正在重新定义collatzList
。
collatzList
| n == 1 = [n]
| otherwise = n:collatzList (collatz n)
这样做:
collatz n
| mod n 2 == 0 = div n 2
| otherwise = 3 * n + 1
collatzList n
| n < 1 = error "Cannot have negative number"
| n == 1 = [n]
| otherwise = n:collatzList (collatz n)
答案 2 :(得分:0)
生成仅依赖于先前值的值列表是unfoldr
函数(Data.List.unfoldr
)的典型应用程序:
import Data.List (unfoldr)
collatzList = unfoldr nextCollatz
where nextCollatz n | n <= 0 = Nothing
| n == 1 = Just (1,0)
| even n = Just (n, n `quot` 2)
| otherwise = Just (n, 3*n+1)
unfoldr f x0
获取起始值x0
,并向其应用函数f
。如果f x0
为Nothing
,则算法终止;如果是Just (push, next)
,则会将push
添加到结果列表中,并使用next
作为x0
的新值。另一个例子,使用展开式生成最大为100的正方形:
import Data.List (unfoldr)
squareList = unfoldr pow2
where pow2 n | n > 100 = Nothing
| otherwise = Just (n, 2*n)
-- "Add n to the result list,
-- start next step at 2*n."
(关于error
的强制性评论:通常最好让函数返回一些虚拟值。例如,在上面的Collatz函数中,非正整数的结果是空列表而不是异常。)