在我的Haskell程序中,我有一个带有许多构造函数的ADT:
data MyData = Con1 |
Con2 |
...
Con20
我有一个foreign export ccall
函数,它将[MyData]
包装到StablePtr's
数组中。在调用它之后,我需要确定使用了哪个构造函数来构造每个元素。
可以通过这种方式解决
foreign export ccall getType :: StablePtr MyData -> IO CInt
getType (Con1) = return 1
getType (Con2) = return 2
...
然后我需要在C头中手动定义这些常量。这很容易出错,所以我想知道是否有办法让GHC为我做这个工作。
答案 0 :(得分:5)
为您的Haskell类型派生Enum
,并导出fromEnumMyData :: MyData -> Int ; fromEnumMyData = fromEnum
。
然后,您可以通过查看GH标签GHC分配来对C侧进行案例分析。
答案 1 :(得分:0)
我找到了解决方案。
我在C代码中将可能的构造函数类型定义为枚举:
typedef enum
{
MyDataCon1,
MyDataCon2,
...
MyDataCon20
} MyDataConstructor;
然后我在我的Haskell源代码中使用了C->Haskell枚举钩:
{#enum MyDataConstructor deriving (Show) #}
预处理后,此行转为
data MyDataConstructor = MyDataCon1
| MyDataCon2
...
| MyDataCon20
现在我可以这样定义getType
:
foreign export ccall getType :: StablePtr MyData -> IO CInt
getType md = do
md' <- deRefStablePtr md
case md' of
Con1 -> return $ fromEnum MyDataCon1
Con2 -> return $ fromEnum MyDataCon2
...
Con20 -> return $ fromEnum MyDataCon20