我有要转换为数据记录的元组列表。元组具有类型(文本,文本),其中第一项是键,第二项是值。
data User = User
{
id :: Text
, name :: Text
}
toUser :: [(Text, Text)] -> User
toUser kvs = ???
在Haskell中是否可以通过其字符串名称设置数据记录的字段名称,就像您通常可以使用反射在C#或Java中一样?
此外,我希望避免重复查找每个字段的列表,并填充一次迭代列表的数据记录,但不确定这样做的最佳选择。
修改
输入列表将类似于此[("id","foo"),("name","bar")]
,因此User
数据记录中的字段名称与列表中的键匹配。
答案 0 :(得分:3)
如果您只想遍历列表一次,我会将元组插入,然后在地图中查找ADT的每个字段名称:
import qualified Data.Map as Map
import Data.Maybe (fromMaybe)
data User = User
{
id :: String
, name :: String
} deriving Show
toUser :: [(String, String)] -> User
toUser xs = User (find "id") (find "name")
where
m = Map.fromList xs
find name = fromMaybe "" $ Map.lookup name m
答案 1 :(得分:2)
@ mb21的想法很容易实现:
import qualified Data.Map.Strict as M
toUser pairs = User idval nameval
where m = M.fromList pairs
idval = M.findWithDefault "?" "id" m
nameval = M.findWithDefault "?" "name" m
但也许把它写成更新函数是个更好的主意?
updateUser :: User -> [(Text,Text)] -> User
updateUser (User i n) pairs = User idval nameval
where m = M.fromList pairs
idval = M.findWithDefault i m
nameval = M.findWithDefault v "name" m