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
,添加您想要的标签。
我是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
,添加您想要的标签。