c - Haskell 到 C - 自定义数据类型

标签 c haskell types

我有以下 Haskell 数据类型:

data RegExp sy  = Empty
    | Epsilon
    | Literal   sy
    | Or        (RegExp sy) (RegExp sy)
    | Then      (RegExp sy) (RegExp sy)
    | Star      (RegExp sy)
deriving (Read, Eq)

我需要从 C 调用它,我想知道是否有人对此有任何经验?我已经用本教程中的简单数据类型完成了它:http://www.haskell.org/haskellwiki/Calling_Haskell_from_C但我不确定该怎么做,因为我有自己定义的数据类型。

显示返回一个字符串,如下所示:

*Language.HaLex.RegExp> let f = (Or a a)
*Language.HaLex.RegExp> :t f
f :: RegExp Char
*Language.HaLex.RegExp> show f
"'a'+'a'"
*Language.HaLex.RegExp> :t show f
show f :: String

但是当我有以下内容时:

simplifyRegExp_hs :: CString -> CString
simplifyRegExp_hs = simplifyRegExp

foreign export ccall simplifyRegExp_hs :: CString -> CString

出现以下错误:

Simplify.hs:317:21:
    Couldn't match type `RegExp t0'
              with `GHC.Ptr.Ptr Foreign.C.Types.CChar'
    Expected type: CString -> CString
      Actual type: RegExp t0 -> RegExp t0
    In the expression: simplifyRegExp
    In an equation for `simplifyRegExp_hs':
        simplifyRegExp_hs = simplifyRegExp

Simplify.hs:319:1:
    Illegal foreign declaration: requires via-C, llvm (-fllvm) or native code    generation (-fvia-C)
    When checking declaration:
      foreign export ccall "simplifyRegExp_hs" simplifyRegExp_hs
        :: CString -> CString
Failed, modules loaded: none.

最佳答案

simplifyRegExp 的类型为 RegExp a -> RegExp a 时,你向编译器声明 simplifyRegExp 的类型为 CString -> CString。您需要先编写实际具有 CString -> CString 类型的函数。这意味着为您的 RegExp 类型提供一个 Read 实例以与 show 实例一起使用。完成后,您可以执行以下操作:

simplifyRegExp_hs :: CString -> IO CString
simplifyRegExp_hs cs = do s <- peekCString cs
                          let reg = read s :: RegExp <element type>
                          newCString (show reg)

如果为您的类型编写Read 实例并不容易,您需要将数据类型编码为 C 结构,并提供从您的 Haskell 类型到 Haskell 中的 C 结构的转换.一般来说,这是更好的解决方案,因为您不必不必要地处理解析器,但如果您的示例足够简单,Read 实例也可以工作。

关于c - Haskell 到 C - 自定义数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23246893/

相关文章:

C - 打开/读取垃圾箱

c++ - C++ 特性有标准限制吗?

c - 动态内存分配和 sizeof()

haskell - 将 Haskell 用于大型实时系统 : how (if? )?

haskell - 需要在 Haskell 中将 16 位无符号大端字节解码为整数

c - 同等不同类型不同尺寸

typescript - 为什么 TypeScript 会提示数组长度?

c++ - 数组类型无效

c++ - C - x+1 没有赋值是什么意思?

c++ - Haskell 堆栈设置 - 无法识别 CPP 程序