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