我可以编译以下内容,但是当我使用:t qsort
时,我会在下面获得长而复杂的类型签名。但是,当我添加它时,程序将不再进行类型检查,无需额外导入(请参阅下面的答案)。我对定义类型的最佳猜测也粘贴在下面,但不要键入check(类型和monad是令人困惑的)。
好的,所以我可以添加一个额外的import语句并进行类型检查,但我从来没有在网上发布的任何代码上看到这个复杂的代码签名。所以我的问题是:
Ord t
并为Int
拨出t
并进行检查,但如何在ST
或IO
中替换为Control.Monad.Primitive.PrimMonad
},我该如何处理v
。我正在尝试编写一个blog post,它提供了如何使用这些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
答案 0 :(得分:4)
导入功能(-s)不会导入其类型。如果您的代码明确引用了类型,则必须导入它。只要代码未明确引用这些类型,您就可以使用导入的函数而无需导入其参数类型或返回值。一旦明确开始使用类型或类,就必须导入它们,这是故意的。
答案 1 :(得分: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