分割代入 (destructuring assignment) は便利というお話。
動機
下記のようなコードを見かけて「オゥ、ナンテコト」と思ったので。
type Hoge a = Hoge (List a)
getList : Hoge a -> List a
getList hoge =
case hoge of
Hoge list ->
list
あと Elm Syntax や Elm ガイド にもちゃんと説明がないようなのでまとめたかった。
カスタム型から値を取り出す
こんな型があったとさ:
-- カスタム型による要素2個のオレオレタプル
type MyTuple a b = MyTuple a b
関数内で値を取り出す
-- タプルの 1個目の要素を返す
first1 : MyTuple a b -> a
first1 tuple =
case tuple of
MyTuple value1 _ ->
value1
先の例もこのパターン。
コンストラクタの数によらず使えるけど、コンストラクタが 1個のときは次の書き方も可能:
-- タプルの 1個目の要素を返す
first1 : MyTuple a b -> a
first1 tuple =
let
(MyTuple value1 _) = tuple
in
value1
引数の時点で値を取り出す (コンストラクタが 1個のときのみ)
first2 : MyTuple a b -> a
first2 (MyTuple value1 _) =
value1
このやり方だと先の getList
はこんな感じに:
getList
getList : Hoge a -> List a
getList (Hoge list) =
list
引数の時点で値を取り出す (コンストラクタが 1個でカスタム型が入れ子のとき)
type Inner a = Inner a
type Outer a = Outer (Inner a)
outerToA : Outer a -> a
outerToA (Outer (Inner value)) =
value
入れ子のときも一括で取り出し可能。
レコード型から値を取り出す
こんな型があったとさ:
-- レコード型による要素2個のオレオレタプル
type alias MyTuple_ a b =
{ value1 : a
, value2 : b
}
よく見るやつ
first0 : MyTuple_ a b -> a
first0 tuple =
tuple.value1
関数内で値を取り出す
first1 : MyTuple_ a b -> a
first1 tuple =
let
{ value1 } = tuple
in
value1
引数の時点で値を取り出す
first2 : MyTuple_ a b -> a
first2 { value1 } =
value1
【NG】引数でレコードの入れ子を展開することはできない
NG
type alias NestedMyTuple_ a b =
{ tuple : MyTuple_ a b
}
firstNg1 : NestedRecord a b -> a
firstNg1 { tuple.value1 } = -- コンパイルエラー
tuple.value1
firstNg2 : NestedRecord a b -> a
firstNg2 { tuple = { value1 } } = -- コンパイルエラー
tuple.value1
レコードの入れ子を更新できないのと同じような話なのかも。
タプル型から値を取り出す
関数内で値を取り出す
first1 : ( a, b ) -> a
first1 tuple =
let
(value1, _) = tuple
in
value1
引数の時点で値を取り出す
first2 : ( a, b ) -> a
first2 ( value1, _ ) =
value1
おわり
変なところ、足りないところあったらコメントください。
おしまり