我正在学习haskell并遇到了这个问题:
使用Glasgow Haskell Compiler, Version 6.10.4, for Haskell 98, stage 2 booted by GHC version 6.10.1
{-# LANGUAGE FlexibleContexts #-}
module UPSO where
import Control.Monad(forM,forM_)
import Control.Monad.ST.Lazy (ST,runST)
import Data.Array.MArray (MArray, Ix, getBounds, newArray, readArray, writeArray)
import Data.Array.ST (STArray,STUArray)
minmax xs@(x:_) = foldr (\x (l,u) -> (min x l,max x u)) (x,x) xs
modify a i f = do
x <- readArray a i
writeArray a i (f x)
increment a i = modify a i (+1)
decrement a i = modify a i (\x -> x - 1)
uniquePermutationsM t 0 = return $! [[]]
uniquePermutationsM t pos = do
(l,u) <- getBounds t
perms <- forM [l..u] (\d -> do
count <- readArray t d -- t[d]
if count == 0
then return $! []
else do
decrement t d
pss <- uniquePermutationsM t (pos-1)
increment t d
return $! (map (d:) pss)
)
return $! (concat perms)
mkArray :: (Int,Int) -> (ST s) (STArray s Int Int)
mkArray bounds = newArray bounds 0
uniquePermutationsST :: [Int] -> ST s [[Int]]
uniquePermutationsST xs = do
let bounds@(l,u) = (minmax xs)
t <- mkArray bounds
forM_ xs (increment t)
pos <- sum `fmap` mapM (readArray t) [l..u]
uniquePermutationsM t pos
uniquePermutations xs = runST (uniquePermutationsST xs)
但是当我尝试切换到未装箱的阵列时,我收到一条错误消息。
mkArray :: (Int,Int) -> (ST s) (STUArray s Int Int)
mkArray bounds = newArray bounds 0
uniquePermutationsST :: [Int] -> ST s [[Int]]
uniquePermutationsST xs = do
let bounds@(l,u) = (minmax xs)
t <- mkArray bounds
forM_ xs (increment t)
pos <- sum `fmap` mapM (readArray t) [l..u]
uniquePermutationsM t pos
uniquePermutations xs = runST (uniquePermutationsST xs)
Could not deduce (MArray (STUArray s) Int (ST s))
from the context ()
arising from a use of 'newArray' at UPSO.hs:35:17-33
Possible fix:
add (MArray (STUArray s) Int (ST s)) to the context of
the type signature for 'mkArray'
or add an instance declaration for (MArray (STUArray s) Int (ST s))
In the expression: newArray bounds 0
In the definition of 'mkArray': mkArray bounds = newArray bounds 0
还有:
Could not deduce (MArray (STUArray s) Int (ST s))
from the context ()
arising from a use of 'increment' at UPSO.hs:41:14-24
经过近两个小时摆弄类型注释后,我希望有人可以指出我正确的方向。到底是怎么回事?
感谢您的时间。
答案 0 :(得分:2)
我在haskell邮件列表上发布了相同的问题并得到了这个答案:
如果我 [使用严格]
Control.Monad.ST
而不是Control.Monad.ST.Lazy
,则此方法有效。问题是为
MArray
monad声明了ST
个实例;似乎没有相应的懒惰ST
monad实例。
- 由Dave Menendez(http://www.eyrie.org/~zednenem/)
没有想到这一点。但有意义的是不定义这些实例,因为未装箱的值不能延迟计算。
Peter Gammie指出,可以应用strictToLazyST
模块的函数Control.Monad.ST.Lazy
在惰性状态线程中使用未装箱的可变数组。请记住,数组的内容仍然是严格的。