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だけ更新