Record syntaxを使うときに設定しておくと便利な言語拡張
Record syntax
を使うときに設定しておくと便利な言語拡張
DuplicateRecordFields
フィールド名の重複を許す。ただし、曖昧になる場合はエラーになる。
Prelude> :set -XDuplicateRecordFields Prelude> data Foo = Foo {x :: Int} Prelude> data Bar = Bar {x :: Char} Prelude> :t Foo Foo :: Int -> Foo Prelude> :t Bar Bar :: Char -> Bar -- ambiguous Prelude> :t x <interactive>:1:1: error: Ambiguous occurrence ‘x’ It could refer to either the field ‘x’, defined at <interactive>:2:17 or the field ‘x’, defined at <interactive>:3:17 Prelude> let f = Foo {x=1} Prelude> let b = Bar {x='a'} -- function application Prelude> x f <interactive>:10:1: error: Ambiguous occurrence ‘x’ It could refer to either the field ‘x’, defined at <interactive>:2:17 or the field ‘x’, defined at <interactive>:3:17 Prelude> let z = x f :: Int <interactive>:12:9: error: Ambiguous occurrence ‘x’ It could refer to either the field ‘x’, defined at <interactive>:2:17 or the field ‘x’, defined at <interactive>:3:17 Prelude> x (f :: Foo) 1 Prelude> x (b :: Bar) 'a' Prelude> Prelude> (\(Foo {x=t}) -> print t) f 1 Prelude> (\(Bar {x=t}) -> print t) b 'a' Prelude> -- record update Prelude> f' = f {x=2} <interactive>:23:6: error: • Record update is ambiguous, and requires a type signature • In the expression: f {x = 2} In an equation for ‘f'’: f' = f {x = 2} Prelude> let f' = f {x=2} :: Foo Prelude> :t f' f' :: Foo Prelude> x (f' :: Foo) 2 Prelude>
NamedFieldPuns
フィールド名の省略
Prelude> :set -XNamedFieldPuns Prelude> data Buzz = Buzz { a :: Int ,b :: Char} deriving Show Prelude> data Buzz = Buzz { a :: Integer ,b :: Char} deriving Show Prelude> Buzz 11 'x' Buzz {a = 11, b = 'x'} Prelude> (\Buzz {a,b} -> print $ (show a) ++ " " ++ (show b) ) $ Buzz 11 'x' "11 'x'"
RecordWildCards
フィールド名のワイルドカード。これを指定しておけばNameFieldPuns
は不要そうな感じ。
Prelude> :set -XRecordWildCards Prelude> (\Buzz {..} -> print $ (show a) ++ " " ++ (show b) ) $ Buzz 11 'x' "11 'x'"