将元组数组转换为数据记录

时间:2016-06-16 11:17:24

标签: haskell

我有要转换为数据记录的元组列表。元组具有类型(文本,文本),其中第一项是键,第二项是值。

data User = User 
  { 
    id :: Text
  , name :: Text 
  }

toUser :: [(Text, Text)] -> User
toUser kvs = ???

在Haskell中是否可以通过其字符串名称设置数据记录的字段名称,就像您通常可以使用反射在C#或Java中一样?

此外,我希望避免重复查找每个字段的列表,并填充一次迭代列表的数据记录,但不确定这样做的最佳选择。

修改

输入列表将类似于此[("id","foo"),("name","bar")],因此User数据记录中的字段名称与列表中的键匹配。

2 个答案:

答案 0 :(得分:3)

如果您只想遍历列表一次,我会将元组插入First Line skip,然后在地图中查找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