2009-07-21 40 views
1

當我在學習Haskell的過程中,碰到這個問題就來了:「無法推斷(MARRAY(STUArray S)INT(ST S))從上下文()」 將runST

使用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 [email protected](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) 

使用STArray(作品)

mkArray :: (Int,Int) -> (ST s) (STArray s Int Int)  
mkArray bounds = newArray bounds 0 

uniquePermutationsST :: [Int] -> ST s [[Int]] 
uniquePermutationsST xs = do 
    let [email protected](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) 

USI的常見開始ng STUArray(不起作用)

但是,當我嘗試切換到unboxed數組時,我收到一條錯誤消息。

mkArray :: (Int,Int) -> (ST s) (STUArray s Int Int)  
mkArray bounds = newArray bounds 0 

uniquePermutationsST :: [Int] -> ST s [[Int]] 
uniquePermutationsST xs = do 
    let [email protected](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 

近兩個小時與類型註釋擺弄之後,我希望有人能指出我在正確的方向。到底什麼地方出了問題?

謝謝你的時間。

+1

似乎爲我工作。也許發佈完整的源代碼來重現問題(理想情況下縮短它,同時還會產生問題)和GHC版本? – yairchu 2009-07-21 19:10:48

回答

2

我已經張貼Haskell的郵件列表上同樣的問題,得到了這樣的回答:

這個作品,如果我[使用嚴格] Control.Monad.ST,而不是Control.Monad.ST.Lazy

問題是MArray實例聲明爲嚴格的ST monad;似乎沒有對應懶惰ST monad的相應實例。
- 由戴維·梅嫩德斯(http://www.eyrie.org/~zednenem/

沒想到這一點。但是有道理不去定義這些實例,因爲unboxed值不能延遲計算。

Peter Gammie指出,可以使用Control.Monad.ST.Lazy模塊的函數strictToLazyST來在懶惰狀態線程中使用unboxed可變數組。請記住,該數組在內容中仍然是嚴格的。

http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad-ST-Lazy.html#v%3AstrictToLazyST

相關問題