4

データ型の不変条件のエンコードに多くの時間を費やしましたが、現在、FFI を介してライブラリを C に公開する作業を行っています。言語の壁を越えてデータ構造をマーシャリングするのではなく、不透明なポインターを使用して C が AST を構築できるようにし、evalHaskell では文字列を C にマーシャリングするだけで済みます。

これは、よりわかりやすくするためのコードです。

-- excerpt from Query.hs
data Sz = Selection | Reduction deriving Show

-- Column Datatype

data Column (a :: Sz) where
    Column  :: String -> Column Selection
    BinExpr :: BinOp  -> Column a -> Column b -> Column (OpSz a b)
    AggExpr :: AggOp  -> Column Selection -> Column Reduction

type family OpSz (a :: Sz) (b :: Sz) where
    OpSz Selection Selection = Selection
    OpSz Selection Reduction = Selection
    OpSz Reduction Selection = Selection
    OpSz Reduction Reduction = Reduction

data Query (a :: Sz) where
    ... etc


-- excerpt from Export.hs

foreign export ccall "selection"
    select :: StablePtr [Column a] -> StablePtr (Query b) -> IO (StablePtr (Query Selection))

foreign export ccall 
    add :: StablePtr (Column a) -> StablePtr (Column b) -> IO (StablePtr (Column (OpSz a b)))

foreign export ccall 
    mul :: StablePtr (Column a) -> StablePtr (Column b) -> IO (StablePtr (Column (OpSz a b)))

foreign export ccall
    eval :: StablePtr (Query Selection) -> IO CString

ただし、私が知る限り、これは型の安全性を無視しているようです。基本的に、C が Haskell に渡すものは何でも、そのタイプであると想定され、Haskell で dsl を書いた理由を完全に否定します。StablePtr を使用してタイプ セーフを維持する利点を得る方法はありますか? 私が最後に望んでいるのは、C で不変式を再実装することです。

4

1 に答える 1