gpt4 book ai didi

haskell - 为 FFI 测试生成有状态函数指针

转载 作者:行者123 更新时间:2023-12-05 05:31:49 25 4
gpt4 key购买 nike

我想使用 QuickCheck 作为外部函数的参数生成有状态函数(C 签名 T f())。最好我还想让它们(或它们内部的 s->(T,s))可显示。

我知道对于无状态函数我可以写类似的东西

type Compare = CInt -> CInt -> CBool
foreign import ccall "wrapper"
mkCompare :: Compare -> IO (FunPtr Compare)

但我在为有状态函数尝试这种方法时遇到了困难,因为我看不出如何将在 Haskell 中隐藏状态的 monad 转换为在 C 中隐藏状态的函数。

有状态函数 f 的示例

static int i = 0;

int f() {
return i++;
}

在 Haskell 中,我将此函数表示为 State (\s -> (s,s+1))

QuickCheck 与它有什么关系?

如果我有一个将有状态函数作为参数的 C 函数,例如

int twice(int (*f)()) {
f();
return f();
}

然后我可以使用 QuickCheck 测试函数,其中 QuickCheck 可以为 f 生成不同的实现,这通常看起来类似于

prop_total (Fun f) xs = total $ g f xs

但这些生成的函数是无状态的,不像上面的示例 C 函数那样是有状态的。

最佳答案

多亏了 Daniel Wagner 在评论中的建议,我才弄明白了。 Show 实例是免费提供的。这是我运行的一个最小示例

gcc -fPIC -shared -o libstateful.dylib stateful.c && ghc -L. Stateful.hs -lstateful && ./Stateful

正如预期的那样,它将输出大约 50% 的 1(真)和 50% 的 0(假)的分布。

Stateful.hs

import Data.IORef
import Foreign.C
import Foreign.Ptr
import System.IO.Unsafe
import Test.QuickCheck

instance CoArbitrary CInt where
coarbitrary = coarbitraryIntegral

instance Arbitrary CBool where
arbitrary = chooseEnum (0,1)
shrink 1 = [0]
shrink 0 = []

instance Function CInt where
function = functionIntegral

type Generator = IO CBool

foreign import ccall "wrapper" mkGenerator :: Generator -> IO (FunPtr Generator)

foreign import ccall "changes" changes :: FunPtr Generator -> IO CBool

type StateFn = CInt -> (CBool,CInt)

stateFnToIORef :: StateFn -> IORef CInt -> IO CBool
stateFnToIORef f s_ref = do
s <- readIORef s_ref
let (a,s') = f s
writeIORef s_ref s'
pure a

prop_changes :: Fun CInt (CBool,CInt) -> Property
prop_changes (Fn f) = unsafePerformIO (do
x_ref <- newIORef 0
f' <- mkGenerator $ stateFnToIORef f x_ref
res <- changes f'
pure $ collect res (total res))

main :: IO ()
main = quickCheck prop_changes

stateful.c

_Bool changes(_Bool (*f)()) {
_Bool x = f();
_Bool y = f();
return x != y;
}

关于haskell - 为 FFI 测试生成有状态函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74272583/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com