2013-09-28 16 views
1

的元素我有數據類型:更改只有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') 

回答

3

記錄更新:

person' = person { person_firstname = newName } 

注意,它適用於任何表達:

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

RecordWildCards擴展還可以節省一些打字,但我推薦它,只能短距離的定義,其中的名稱不能從你走:

incrementId [email protected]{..} = person { person_id = person_id + 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 

鏡頭具有的優點是它們容易可組合;他們派上用場,當你嵌套數據結構。