仅更改复合数据类型的1个元素

时间:2013-09-28 20:16:24

标签: haskell

我有数据类型:

data Person  = Person {
    person_id :: Int,
    person_firstname :: String,
    person_surname :: String,
    person_address :: Address
}

我想更改让我们说person_firstname的值,其中haskell意味着复制其他所有内容。有没有比这更简单的方法:

        person'' = Person (person_id person') newName (person_surname person') (person_address person')

2 个答案:

答案 0 :(得分:3)

记录更新:

person' = person { person_firstname = newName }

请注意,它适用于任何表达式:

somebody = (Person 0 "Nobody" "Nothingson" "123 Fake St.")
  { person_firstname = "Somebody"
  , person_surname = "Somethingson"
  }

RecordWildCards扩展程序还可以为您节省一些打字费用,但我建议您仅将其用于名称离不开您的简短定义:

incrementId person@Person{..} = person { person_id = person_id + 1 }

答案 1 :(得分:2)

另一种方法是使用lens包中的镜片:

{-# LANGUAGE TemplateHaskell #-}

import Control.Lens

data Person  = Person {
    _person_id :: Int,
    _person_firstname :: String,
    _person_surname :: String,
    _person_address :: String
}

makeLenses ''Person

examplePerson = Person 7 "aaa" "bbb" "ccc"

modifiedPerson = set person_firstname "zzz" examplePerson

main :: IO ()
main = do
    putStrLn $ view person_firstname modifiedPerson

镜片的优点是它们易于组合;当你有嵌套的数据结构时,它们会派上用场。