如何使HaXml和DrIFT与GHC 7.0.3一起使用?

时间:2011-09-21 13:57:40

标签: xml serialization haskell persistence

我正在寻找在Haskell和Java / Scala / C#代码之间交换数据的解决方案。目前,我正在考虑使用XML。理想情况下,我希望从我的Haskell数据类型生成XML模式。我的第一次尝试是HaXml 1.22.2,Drift 2.2.2。全部在GHC 7.0.3上。有以下片段:

import Data.List (isPrefixOf)
import Text.XML.HaXml.XmlContent
import Text.XML.HaXml.Types
import Text.XML.HaXml.Pretty (document)

data MyType = A | B String deriving (Eq, Show)
      {-! derive : XmlContent !-}   -- this line is for DrIFT

从这个文件中,DrIFT产生:

{- Generated by DrIFT (Automatic class derivations for Haskell) -}
{-# LINE 1 "ts.hs" #-}
import Data.List (isPrefixOf)
import Text.XML.HaXml.XmlContent
import Text.XML.HaXml.Types
import Text.XML.HaXml.Pretty (document)


data MyType = A | B String deriving (Eq, Show)
      {-! derive : XmlContent !-}   -- this line is for DrIFT
{-* Generated by DrIFT : Look, but Don't Touch. *-}
instance HTypeable MyType where
    toHType v =
    Defined "MyType" [] [Constr "A" [] [],Constr "B" [] [toHType aa]]
      where
    (B aa) = v
instance XmlContent MyType where
    parseContents = do
    { e@(Elem t _ _) <- elementWith (flip isPrefixOf) ["B","A"]
    ; case t of
      _ | "B" `isPrefixOf` t -> interior e $ fmap B parseContents
        | "A" `isPrefixOf` t -> interior e $ return A
    }
    toContents v@A =
    [mkElemC (showConstr 0 (toHType v)) []]
    toContents v@(B aa) =
    [mkElemC (showConstr 1 (toHType v)) (toContents aa)]

--  Imported from other files :-

使用GHC编译此代码会产生错误消息:

19:32:
    Couldn't match expected type `[Char]' with actual type `QName'
    In the second argument of `isPrefixOf', namely `t'
    In the expression: "B" `isPrefixOf` t
    In a stmt of a pattern guard for
                 a case alternative:
          "B" `isPrefixOf` t

是工具问题还是我做错了?如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

旧版HaXml的Hackage文档中的Diggin在版本1.20.2及更早版本中显示Elem数据构造函数used to take a Name,它只是String的类型同义词。但是,在该版本与版本1.22.3之间的某个时间,它已更改为QName,即a custom data type

因此,对元素名称使用isPrefixOf对旧版本有效是有意义的,但对于较新版本则无效。

从这些版本的上传日期开始,这发生在去年的某个时间,而DrIFT自2009年以来似乎没有更新过。

您应该通知DrIFT维护者。同时,您可以使用旧版本的HaXml或自己编写实例来解决它。您应该能够使用不正确的生成实例作为起点。

答案 1 :(得分:0)

我最近使用Apache Thrift项目成功集成了Haskell和Python。 Thrift编译器处理数据和服务定义文件,以在必要的语言中生成代码,以创建无缝地将消息传递给彼此的客户端和服务器。

答案 2 :(得分:0)

未经测试的修正:

1)将导入Data.List(isPrefixOf)的行更改为

import qualified Data.List(isPrefixOf) as List

2)添加此代码:

isPrefixOf (N n)    = List.isPrefixOf n
isPrefixOf (QN _ n) = List.isPrefixOf n

我不确定这是否为合格的名字提供了预期的行为。