【发布时间】:2014-02-14 12:43:33
【问题描述】:
我想学习使用 ST-Monad。因此,我想为每个整数重写一些代码计算——直到一个限制——所有正确除数的列表。结果应该是一个数组,索引“n”的条目应该是它的正确除数列表。
这是通过为每个整数“n”计算其倍数的列表“l”并在索引“m”处将“l”中的每个倍数“m”添加到列表中的除数“n”来完成的。
这是我要修改的代码:
properDivisorsOf' :: forall a. (Integral a, Ix a) => a -> Array a [a]
properDivisorsOf' limit =
let generate :: (Integral a, Ix a) => a -> Array a [a] -> Array a [a]
generate n acc
| n > (limit `div` 2) = acc
| otherwise =
let acc' = acc // [(i, n : (acc ! i)) | i <- [2*n, 3*n .. limit]]
in generate (n + 1) acc'
in generate 1 (array (1, limit) [(i, [])| i <- [1..limit]])
我就是这样尝试的:
properDivisorsOf :: forall a. (Integral a, Ix a) => a -> Array a [a]
properDivisorsOf limit =
let result :: ST s (STArray s a [a])
result = newArray (1, limit) [] -- In the beginning for every number: no divisors known (empty list)
update (index, divisor) = do
l <- readArray result index -- extracting list of divisors of number 'index'
let u = divisor : l
writeArray result index u -- and adding 'divisor' to the list
content :: [(a, a)]
content = do
n <- [1 .. (limit `div` 2)]
multiple <- [2*n, 3*n .. limit]
return (multiple, n)
doUpdate = map update content -- update result for all multiples (in content)
在 runSTArray 结果中
不幸的是,它没有编译,并且错误消息对我没有任何意义。我有两个问题:
- 为什么不能编译?如何正确提取条目?
- 一个有经验的 Haskell 程序如何在他必须使用 ST-Monad 的限制下解决这个问题(为了提高效率)
编辑:编译器消息
Couldn't match expected type `[t0]'
with actual type `STArray i0 a [a]'
In the second argument of `(:)', namely `l'
In the expression: divisor : l
In an equation for `u': u = divisor : l
失败,已加载模块:无。
【问题讨论】:
-
如果您想知道编译器在抱怨什么,向我们展示错误消息可能会有所帮助。