簡體   English   中英

Haskell:簡化了:t提供的可變矢量類型簽名

[英]Haskell: simplifying a mutable vector type signature provided by :t

我可以編譯以下內容,但是當我使用:t qsort時,我在下面得到了長而復雜的類型簽名。 但是,當我添加該代碼時,該程序將不再進行類型檢查,而不會進行其他導入(請參見下面的答案)。 我對定義類型的最佳猜測也粘貼在下面,但不要進行類型檢查(類型和monad令人困惑)。

好的,所以我可以添加一個額外的import語句並進行類型檢查,但是我從未在任何在線發布的代碼中看到過如此復雜的代碼簽名。 所以我的問題是:

  • 我可以刪除Ord t並為t擴展Int並對其進行檢查,但是如何用STIO代替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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM