1

我有数据类型:

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')
4

2 回答 2

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 }
于 2013-09-28T20:18:18.617 回答
2

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

{-# 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

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

于 2013-09-28T21:52:32.517 回答