haskell:レコード構文
代入しているように見える。
レコード構文のシンタックス
定義
data Person = Person { firstName :: String , lastName :: String , age :: Int , height :: Float , phoneNumber :: String , flavor :: String } deriving (Show)
構築
1つ目
let guy = Person "Buddy" "Finklestein" 43 184.2 "526-2928" "Chocolate"
2つ目
let guy = Person { firstName = "Buddy" , lastName = "Finklestein" , age = 43 , height = 184.2 , phoneNumber = "526-2928" , flavor = "Chocolate" }
2つ目の書式でPersonを構築するときは、すべてのフィールドを指定しなくてもいい。(ただしフィールドが「インスタンス化されていない」という警告が出る)
main :: IO () main = do let guy = Person { firstName = "Buddy" , lastName = "Finklestein" , age = 43 -- , height = 184.2 , phoneNumber = "526-2928" , flavor = "Chocolate" } print guy
> :l main.hs [1 of 1] Compiling Main ( main.hs, interpreted ) main.hs:11:13: Warning: Fields of `Person' not initialised: height In the expression: Person {firstName = "Buddy", lastName = "Finklestein", age = 43, phoneNumber = "526-2928", flavor = "Chocolate"} In an equation for `guy': guy = Person {firstName = "Buddy", lastName = "Finklestein", age = 43, phoneNumber = "526-2928", flavor = "Chocolate"} In the expression: do { let guy = ...; print guy } Ok, modules loaded: Main.
遅延評価のため、インスタンス化されていないフィールドを使ったタイミングで例外を送出する。
Person {firstName = "Buddy", lastName = "Finklestein", age = 43, height = *** Ex ception: main.hs:(11,13)-(17,18): Missing field in record construction Main.height
構築2
ここで構築済みのPerson値に、2つ目の書式でフィールドの調整をすることができる。
main :: IO () main = do let guy = Person { firstName = "Buddy" , lastName = "Finklestein" , age = 43 -- , height = 184.2 , phoneNumber = "526-2928" , flavor = "Chocolate" } print guy {height = 184.2}
> main Person {firstName = "Buddy", lastName = "Finklestein", age = 43, height = 184.2, phoneNumber = "526-2928", flavor = "Chocolate"}
応用例
状態保持。
XXX
処理分割。
data Foo { turn :: XXX , time :: XXX , a :: XXX } foo f = final f where mae_shori = Foo (turn f + 1) (time f % 2) final = mae_shori {a = xxx} -- aだけ更新