5

在我的 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 为我完成这项工作。

4

2 回答 2

6

Enum为您的 Haskell 类型派生,然后导出fromEnumMyData :: MyData -> Int ; fromEnumMyData = fromEnum

然后您可以通过查看 GHC 分配的 Int 标签来在 C 端进行案例分析。

于 2012-07-02T14:51:57.607 回答
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
于 2012-12-15T16:44:34.070 回答