我想我有一個簡單的問題,但我無法解決它:我想創建一個向量,在這個向量上呼叫 FFI 并回傳它。
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-Monads,所以應該可以轉換它們吧?
uj5u.com熱心網友回復:
對于 FFI 應用程式,通常最簡單的方法是根本不用理會并ST在IO. 如果您必須有一個純介面(并且您的 FFI 函式實際上是所需的純介面),您可以呼叫unsafePerformIO來提供一個純介面。
withCarray但是,我想我會像你在這里所做的那樣回避寫作。抽象很好,但是通過傳遞行為不合適的回呼很容易意外誤用。如果你必須擁有它,至少命名它unsafeWithCarray并留下一個黑線鱈明確說明在什么情況下它是安全的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/423020.html
標籤:
