[英]What's going on in this type signature? (Vector.Mutable modifiers in Haskell)
[英]Haskell: simplifying a mutable vector type signature provided by :t
我可以編譯以下內容,但是當我使用:t qsort
時,我在下面得到了長而復雜的類型簽名。 但是,當我添加該代碼時,該程序將不再進行類型檢查,而不會進行其他導入(請參見下面的答案)。 我對定義類型的最佳猜測也粘貼在下面,但不要進行類型檢查(類型和monad令人困惑)。
好的,所以我可以添加一個額外的import語句並進行類型檢查,但是我從未在任何在線發布的代碼中看到過如此復雜的代碼簽名。 所以我的問題是:
Ord t
並為t
擴展Int
並對其進行檢查,但是如何用ST
或IO
代替Control.Monad.Primitive.PrimMonad
,以及如何使用v
。 我正在嘗試寫一篇博客文章 ,提供一個如何使用這些各種Monad的示例,相比之下,對於Arrays,qsort的類型簽名是一個更易於管理的qsort :: (STArray s Int Int) -> Int -> Int -> ST s ()
。 (對於那些想了解s
,在線上有很多解釋,所有這些解釋都超出了我的理解范圍—我知道,獲得類型檢查器本身是一個聰明的竅門,以防止作者在代碼中編寫來自Monad的數據泄漏出去,從而導致雜質。)
import Control.Monad
import Control.Monad.ST
import qualified Data.Vector as V
import qualified Data.Vector.Generic.Mutable as MV
main = do
lines <- BS.lines `fmap` BS.readFile "10.txt"
let
inputData = Prelude.map (maybe (error "can't read Int") fst . BS.readInt) lines
initialImmutableVector = V.fromList inputData
print $ runST $ do
state <- V.thaw initialImmutableVector
qsort state 0 (Prelude.length inputData - 1)
frozen <- V.freeze state
return frozen
--qsort :: (MV.MVector s Int) -> Int -> Int -> ST s ()
--qsort
-- :: (Ord t, Control.Monad.Primitive.PrimMonad m, MV.MVector v t) =>
-- v (Control.Monad.Primitive.PrimState m) t -> Int -> Int -> m ()
qsort vec min mx =
if mx - min < 1 then
return ()
else do
p <- MV.read vec min
final_i <- foldM (partitioner p) (min+1) [(min+1)..mx]
swap min (final_i - 1)
qsort vec min (final_i-2)
qsort vec final_i mx
where
swap i j = do
vec_i <- MV.read vec i
vec_j <- MV.read vec j
MV.write vec i vec_j
MV.write vec j vec_i
partitioner p i acc = do
vec_acc <- MV.read vec acc
if vec_acc > p then
return i
else do
swap i acc
return $ i+1
導入函數不導入其類型。 如果您的代碼明確引用了該類型,則必須將其導入。 您可以使用導入的函數而無需導入其參數或返回值的類型,只要代碼未明確引用這些類型即可。 一旦開始明確使用類型或類,就必須導入它們,這是有意的。
看來您的上一次嘗試是正確的,但是也許您沒有導入所需的所有內容? 您粘貼為原樣的代碼不帶有或不帶有類型簽名。 這是您所擁有內容的略微修改版本,對我來說很好用(使用GHC 7.8.3):
import Control.Monad
import Control.Monad.ST
import qualified Data.Vector as V
import qualified Data.Vector.Generic.Mutable as MV
import qualified Data.ByteString.Char8 as BS
import Control.Monad.Primitive (PrimState, PrimMonad)
import Prelude hiding (lines, min)
main :: IO ()
main = do
lines <- BS.lines `fmap` BS.readFile "10.txt"
let
inputData = map (maybe (error "can't read Int") fst . BS.readInt) lines
initialImmutableVector = V.fromList inputData
print $ runST $ do
state <- V.thaw initialImmutableVector
qsort state 0 (Prelude.length inputData - 1)
frozen <- V.freeze state
return frozen
qsort :: (Ord t, PrimMonad m, MV.MVector v t)
=> v (PrimState m) t -> Int -> Int -> m ()
qsort vec min mx =
if mx - min < 1 then
return ()
else do
p <- MV.read vec min
final_i <- foldM (partitioner p) (min+1) [(min+1)..mx]
swap min (final_i - 1)
qsort vec min (final_i-2)
qsort vec final_i mx
where
swap i j = do
vec_i <- MV.read vec i
vec_j <- MV.read vec j
MV.write vec i vec_j
MV.write vec j vec_i
partitioner p i acc = do
vec_acc <- MV.read vec acc
if vec_acc > p then
return i
else do
swap i acc
return $ i+1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.