你好,我面临以下问题。我有一个具有多个字段的数据类型。我需要枚举它们并将它们存储在一个集合中以进行进一步的映射。
data Worker=Worker{
age::Int,
name::String,
title::Title,
income::Int
}
data Title=Manager | Dev | Tester deriving (Show)
instance Show Worker where
show w=let !names=["age","name", "title","income"]
!props= [age,name,title,income] in -- Do i need to define another new type to be able to flat them down to a list?
"{"++intercalate "," (zipWith (\x y-> x++":"++ y w) names props)++"}"
在我们的例子中,我可以在哪里存储所有属性(方法),以便能够进一步将它们用作高阶函数中类型为Worker
的给定变量的参数。
答案 0 :(得分:1)
您可以大致上找到想要的东西,但这不会很漂亮。
我们可以使用RecordWildCards
来将所有访问器名称都视为作用域,就好像它们是普通变量一样,但这仍然引入了一个新问题。
-- Not runnable Haskell code
foo Worker {..} = let names = ["age", "name", "title", "income"]
props = [age, name, title, income]
in ...
我们正在Worker {..}
上进行模式匹配,这将大量访问器名称引入本地范围。但是,props
试图成为异构列表,Haskell不允许这样做。它包含两个整数,一个字符串和一个标题,而Haskell列表仅应包含一种类型。
由于要显示每个字段,因此必须手动将show
应用于每个元素。就像我说的那样,这将有点难看。
foo Worker {..} = let names = ["age", "name", "title", "income"]
props = [show age, show name, show title, show income]
in ...
貌似我们可以map show [age, name, title, income]
,但我们做不到。该列表仍然无效,并且我们在此处应用了三个不同的show
函数(它们恰好共享一个名称),因此我们无法有意义地映射 same { {1}}在每个元素上。
但是,正如评论所说,您最好的选择是熟悉一个合适的JSON库,而Aeson无疑是Haskell中此类事情的最佳选择。