2017-02-12 63 views
0

我想做runST內蘭德-單子,但我不能得到正確的類型,並從GHC輸出不是特別有幫助:輸入runST內MonadRandom

import   Control.Monad 
import   Control.Monad.Random as MR 
import   Control.Monad.ST 
import   Control.Monad.Trans 
import qualified Data.Vector.Unboxed as VU 

shuffle :: (MonadRandom m) => m (VU.Vector Int) 
shuffle = do 
    k <- getRandomR (0::Int, 10::Int) 
    let vec = runST $ do 
    vector <- VU.unsafeThaw (VU.enumFromN (1::Int) k) 
    vector' <- VU.unsafeFreeze vector 
    return vector 
    return vec 

解析錯誤`矢量'

回答

2

該錯誤通常與縮進問題有關。如果您將runST塊中的行縮進多一點,則該錯誤將消失。

下一個問題是,你正在返回錯誤的矢量(忘了')。

最後,綁定僅用於下一行的返回函數的值是多餘的。

這裏是工作代碼:

shuffle :: (MonadRandom m) => m (VU.Vector Int) 
shuffle = do 
    k <- getRandomR (0::Int, 10::Int) 
    let vec = runST $ do 
       vector <- VU.unsafeThaw (VU.enumFromN (1::Int) k) 
       VU.unsafeFreeze vector 
    return vec 

另外,

shuffle :: (MonadRandom m) => m (VU.Vector Int) 
shuffle = do 
    k <- getRandomR (0::Int, 10::Int) 
    return $ runST $ do 
    vector <- VU.unsafeThaw (VU.enumFromN (1::Int) k) 
    VU.unsafeFreeze vector 
+0

優秀。雙空間縮進標籤真的很容易錯過。爲什麼沒有必要將'runST'提升到隨機monad中?返回句柄嗎? – tsorn

+1

'runST'返回一個純粹的值(在這種情況下是你的向量),'return'將這個值放入monad中。 – Erik

+0

或者完全忘記'做',因爲它所做的只是讓你發明一個臨時向量的名字:'return。 runST $ VU.unsafeThaw(VU.enumFromN(1 :: Int)k)>> = VU.unsafeFreeze' – amalloy