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

Haskell タイプの派生Enum、および export 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 フックを使用しました。

{#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 に答える