Haskell 将 adt 呈现为 xml 设计问题

Haskell rendering adt as xml design problem

我是haskell的初学者,在一个玩具项目中碰壁了。我只是想模拟一个单元和一个容器,可以将单元和容器作为成员。我想将单元和容器序列化为 xml 之后可能是其他格式。 这是我目前所拥有的

module Model where
import           Data.Map                       ( Map )  -- importing type
import           Data.Text                      ( Text )

data ModelInfo = InfoCons {
                    modelId :: Text, modelType :: Text,
                    modelAttrs :: Map Text Text
                } deriving (Show, Eq)

data UnitModel = UnitCons { unitInfo :: ModelInfo, unitData :: Text} deriving (Show, Eq)

data ContainerModel = ContainerCons {  containerInfo :: ModelInfo
                       , containerData :: [ContainerData]} deriving (Show, Eq)


data ContainerData = NestedCons ContainerModel
                    | SimpleCons UnitModel
                     deriving (Show, Eq)

这些是我的模型。他们的灵感主要来自 here。 这是我的渲染函数:


class ModelRenderer model where
    -- function definition
    addIdType2Props :: (model -> ModelInfo) -> model -> Map Txt.Text Txt.Text
    addIdType2Props f mdl = add2Map
        (modelAttrs (f mdl))
        [(Txt.pack "id", modelId (f mdl)),
         (Txt.pack "type", modelType (f mdl))]

    makeElement :: model -> Xml.Element


-- transform unit model to xml

instance ModelRenderer UnitModel where
    makeElement um = Xml.Element
        { Xml.elementName       = makeName (Txt.pack "unit")
        , Xml.elementAttributes = convertTxt2NameMap
                                      (addIdType2Props unitInfo um)
        , Xml.elementNodes      = [Xml.NodeContent (unitData um)]
        }


-- transform container model to xml
instance ModelRenderer ContainerModel where
    makeElement cm = Xml.Element
        { Xml.elementName       = makeName (Txt.pack "container")
        , Xml.elementAttributes = convertTxt2NameMap
                                      (addIdType2Props containerInfo cm)
        , Xml.elementNodes      = map (Xml.NodeElement . makeElement)
                                      (containerData cm)
        }

问题是我不知道如何用我目前对 haskell 的了解来渲染 ContainerData。我想对构成 ContainerData 的值进行类型检查,但我知道这不是 haskell 方式。有什么建议吗?

我认为您可以为此使用模式匹配。像

instance ModelRenderer ContainerData where
    makeElement (NestedCons cm) = makeElement cm
    makeElement (SimpleCons um) = makeElement um

您可以将其改编成完整的ContainerModel,添加您想要的标签。