我想我有一个简单的问题,但我无法解决:我想要创建一个向量,调用这个向量并返回它。
import qualified Data.Vector.Storable as VS
import qualified Data.Vector.Storable.Mutable as VSM
withCarray :: Int -> (Ptr Float -> IO ()) -> (Vector Float)
withCarray n f = VS.create $ do
v <- VSM.new n
VSM.unsafeWith v f
return v现在,VSM.unsafeWith返回一个IO,这是在ST Monad中。但是,如果我使用ioToST或liftIO,就会遇到以下问题:
Couldn't match type ‘s’ with ‘RealWorld’
‘s’ is a rigid type variable bound by
a type expected by the context:
forall s. ST s (VSM.MVector s Float)
at src/Interpolation.hs:(60,30)-(63,10)
Expected type: ST s (VSM.IOVector Float)
Actual type: ST s (VSM.MVector (PrimState (ST s)) Float)知道吗,我怎样才能把unsafeWith转换成正确的Monad?我看到IO和ST都是Prim,所以应该可以转换它们,对吗?
发布于 2022-01-21 18:51:34
对于FFI应用程序来说,最简单的方法通常是完全不用使用ST,而是在IO中做任何事情。如果您必须有一个纯接口(而且您的FFI函数实际上在所需的方式上是纯的),您可以调用unsafePerformIO来提供一个纯接口。
但是,我想我会像你在这里所做的那样,不愿写withCarray。抽象是很好的,但是这太容易通过传递一个不适当的回调来意外地被滥用。如果您必须拥有它,至少可以将其命名为unsafeWithCarray,并留下一个哈多克显式地说明在什么情况下是安全的。
https://stackoverflow.com/questions/70799249
复制相似问题