Haskell 在runST函数中传递作用域状态
我有一个如下所示的测试函数,它使用Haskell 在runST函数中传递作用域状态,haskell,st,Haskell,St,我有一个如下所示的测试函数,它使用runST对状态进行内部变异。我在其中定义了另一个函数go,它返回Int作为结果包装在ST中(只是玩一些ST概念)。问题是我的函数类型签名似乎是错误的。如果我注释掉函数类型签名,代码运行良好。对于注释代码中的类型签名,它不会编译,因为编译器将go函数的状态解释为与封闭范围中的状态不同。我将非常感谢关于如何定义函数类型签名以将外部ST s传递到go函数的指针 {-# LANGUAGE ScopedTypeVariables #-} module Main wher
runST
对状态进行内部变异。我在其中定义了另一个函数go
,它返回Int
作为结果包装在ST
中(只是玩一些ST
概念)。问题是我的函数类型签名似乎是错误的。如果我注释掉函数类型签名,代码运行良好。对于注释代码中的类型签名,它不会编译,因为编译器将go
函数的状态解释为与封闭范围中的状态不同。我将非常感谢关于如何定义函数类型签名以将外部ST s
传递到go
函数的指针
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Data.Word(Word32)
import Data.Vector.Unboxed as U hiding (mapM_,create)
import Control.Monad.ST as ST
import Control.Monad.Primitive (PrimState)
import System.Random.MWC
test :: Word32 -> Int
test x = runST $ do
gen <- initialize (U.singleton $ fromIntegral x :: U.Vector Word32) :: (forall s. ST s (Gen (PrimState (ST s))))
let --go :: Int -> ST s Int
go x = do
v <- uniformR (1,x) gen
return v
i <- go 100
return i
这不是一个完整的答案,但我也可以通过传递
gen
:
test :: Word32 -> Int
test x = runST $ do
gen <- initialize (U.singleton $ fromIntegral x :: U.Vector Word32) :: (forall s. ST s (Gen (PrimState (ST s))))
let go3 :: (Num b, Variate b) => Gen (PrimState (ST s)) -> b -> ST s b
go3 g x' = uniformR (1,x') g
go3 gen 100
test::Word32->Int
测试x=runST$do
gen gen(原始状态(ST s))->b->ST s b
go3 g x'=uniformR(1,x')g
go3 gen 100
问题是当你说
gen <- ... :: (forall s. ST s (Gen (PrimState (ST s))))
v <- uniformR (1,x) gen
相当于
let go :: forall s. Int -> ST s Int
i、 例如,go
必须适用于任何s
。但是你说
gen <- ... :: (forall s. ST s (Gen (PrimState (ST s))))
v <- uniformR (1,x) gen
在这之后,s
将被正确地确定范围。是的,这显然是缺少范围的解决办法……我以前做过,并且想避免它。因此,这个问题。按照您的建议移动类型定义,可以解决这个问题。不过,我不清楚为何要这样做。所以,暂时不要打开它。@Sal,这是因为ScopedTypeVariables是如何工作的。您可以使用::forall s..绑定类型变量
或在lambda绑定中,例如\(x::[a])->{-a在这里绑定-}
。一元结合脱糖与lambda结合。
(gen :: Gen (PrimState (ST s))) <- initialize ...