我试图实现标题所说的,但由于懒惰的评估,我无法得到结果:
data AlgorithmM = AlgorithmM {fm::[Int],fa::[Int],fj::Int,fn::Int}
m1a :: AlgorithmM->(IO (),AlgorithmM)
m1a (AlgorithmM m a j n) = (return (),AlgorithmM (2:m) a j n)
m1b :: AlgorithmM->(IO (),AlgorithmM)
m1b (AlgorithmM m a j n) = (return (),AlgorithmM m (take n $! repeat 0) j n)
m2 algo = (visit False $ fa algo,algo)
where visit True l =do
mapM (\z->putStr $ show z) l
putStr "\n"
visit False (x:xs) = do
mapM (\z->putStr $ show z) xs
putStr "\n"
initN :: AlgorithmM->(IO (),AlgorithmM)
initN (AlgorithmM m a j n) = (return (),AlgorithmM m a j ((length m)-1))
m3 :: AlgorithmM->(IO (),AlgorithmM)
m3 (AlgorithmM m a j n) = (return (),AlgorithmM m a n n)
m4 :: AlgorithmM->(IO (),AlgorithmM)
m4 (AlgorithmM m a j n) = if (a !! j) == (m !! j) - 1 then m4 (AlgorithmM m (setajZero a j) (j-1) n) else (return (),AlgorithmM m a j n)
where setajZero (x:xs) 0 = 0:xs
setajZero (x:xs) j = x:(setajZero xs (j-1))
m5 :: AlgorithmM->(IO (),AlgorithmM)
m5 (AlgorithmM m a j n) = if j==0 then (return (),AlgorithmM m a j n) else m2 (AlgorithmM m a j n)
bind :: (IO(),AlgorithmM)->(AlgorithmM->(IO (),AlgorithmM))->(IO(),AlgorithmM)
bind g f = f $! snd g
testAlgorithmM = m1a (AlgorithmM [2,2,2] [] 0 0) `bind` initN `bind` m1b `bind` m2 `bind` m3 `bind` m4 `bind` m5
main = do
let (x,y) = testAlgorithmM
x
当我将上面的代码运行到解释器时,我采取
例外:前奏曲。(!!):索引太大
我认为 m1a 中的列表没有扩展 n+1 所以 m4 抛出异常
有任何想法吗?谢谢。