【发布时间】:2015-01-14 21:53:22
【问题描述】:
使用RankNTypes,我定义了一个不依赖于类型变量的类型。这是解决以下案例的正确方法吗?
我需要定义一些在ST s 中使用的函数,当然,这些函数并不依赖于s。然而,这会导致一个问题,即应用了两个Ints 的Exp 表达式不会导致Block。为什么?
这是一个复制器:
import Control.Monad.ST
import Data.Vector.Unboxed (Vector)
import qualified Data.Vector.Unboxed as U
import Data.Vector.Unboxed.Mutable (STVector)
import qualified Data.Vector.Unboxed.Mutable as UM
type Exp = Int -> Int -> Block
type Block = forall s . STVector s Int -> ST s Int
block :: [Block] -> Block
block [] _ = return 0 -- mapM doesn't work, either - ok, I kinda see why
block (e:es) a = do x <- e a
xs <- block es a
return $ x+xs
copy :: Exp
copy i j a = do
aj <- a `UM.unsafeRead` j
UM.unsafeWrite a i aj
return 1
f :: Block -> Vector Int -> Int
f blk ua = runST $ U.thaw ua >>= blk
g :: Block -> Int
g blk = f blk $ U.fromListN 12 [1..]
main = print . g $ block [copy 10 1]
我在最后一行得到点的错误:
Couldn't match type `STVector s0 Int -> ST s0 Int'
with `forall s. STVector s Int -> ST s Int'
Expected type: Block
Actual type: STVector s0 Int -> ST s0 Int
In the return type of a call of `block'
Probable cause: `block' is applied to too few arguments
In the second argument of `($)', namely `block [copy 10 1]'
In the expression: print . g $ block [copy 10 1]
据我所知,预期类型和实际类型之间的区别在于 forall s. 位。
【问题讨论】: