この記事は (bouzuya) PureScript Advent Calendar 2016 の 14 日目。 (bouzuya) PureScript Advent Calendar 2016 は bouzuya の PureScript 学習の記録だ。
- ← 13 日目『 PureScript by Example の 5 章の前半を読む - Qiita 』
- → 15 日目『 PureScript by Example の 5.10, 5.11 を読む - Qiita 』
概要
PureScript by Example を PureScript Language Guide や Pursuit を見ながら進めていく。
今日は 5.7 から読んでいく。
※注意事項: 英語と日本語訳では大きな差異がある。0.10.x
に対応している英語の側で進める。
- PureScript by Example 2016-12-05 時点で 0.10.x 向け
- 実例による PureScript 2016-12-05 時点で 0.7 向け
- PureScript Language Guide 対象バージョン不明
前回のおさらい
この章では代数的データ型 (algebraic data type) とパターンマッチ (pattern matching) および行多相 (row polymorphism) を扱うらしい。
Number
String
Char
Boolean
Array
のパターンマッチを見た。またガードを書くことでさらに分岐できるのを見た。
Language Guide:
PureScript by Example 5.7
Record
パターン。
showPerson :: { first :: String, last :: String } -> String
showPerson { first: x, last: y } = y <> ", " <> x
JavaScript の分割代入で別名指定したときっぽい構文。
> :type showPerson
{ first :: String
, last :: String
}
-> String
あれ、PureScript by Example に書いてあるものと動きが違うぞ……。
> showPerson { first: "Phil", last: "Freeman", location: "Los Angeles" }
Error found:
in module $PSCI
at line 1, column 1 - line 1, column 70
Type of expression contains additional label location.
while checking that expression { first: "Phil"
, last: "Freeman"
, location: "Los Angeles"
}
has type { first :: String
, last :: String
}
while applying a function showPerson
of type { first :: String
, last :: String
}
-> String
to argument { first: "Phil"
, last: "Freeman"
, location: "Los Angeles"
}
in value declaration it
See https://github.com/purescript/purescript/wiki/Error-Code-AdditionalProperty for more information,
or to contribute content related to this error.
やはりエラーになる。
showPerson :: forall r. { first :: String, last :: String | r } -> String
showPerson { first: x, last: y } = y <> ", " <> x
> import Main
> showPerson { first: "Phil", last: "Freeman", location: "Los Angeles" }
"Freeman, Phil"
> :t showPerson
forall r.
{ first :: String
, last :: String
| r
}
-> String
これで例どおりに動く。
PureScript by Example 5.8
ネストしても良い。なるほど。
type Address = { street :: String, city :: String }
type Person = { name :: String, address :: Address }
livesInLA :: Person -> Boolean
livesInLA { address: { city: "Los Angeles" } } = true
livesInLA _ = false
PureScript by Example 5.9
@
を使えばスコープに名前をつけることができる。ふむ、言葉で言われてもよく分からないけど、マッチさせる前のものを得られるってことみたいだ。
sortPair :: Array Int -> Array Int
sortPair arr@[x, y]
| x <= y = arr
| otherwise = [y, x]
sortPair arr = arr
これはたまに要るのでありがたい。
まとめ
これまた中途半端だけど、時間の都合でここまで。
参考
- PureScript by Example
- 実例による PureScript
- paf31/purescript-book
- Language Guide
- Language Guide - Top-level declarations
次回以降の TODO
- PureScript by Example & PureScript Language Guide を読み進める
-
Array
以外でのdo
記法 - Tagged Unions / Newtype
psc-package
- PureScript IDE の導入
- 24 Days of PureScript, 2016
- 24 Days of PureScript, 2014
- 某氏の記事の紹介
- github.com/purescript のコードを読む
- github.com/purescript-node のコードを読む
- github.com/purescript-contrib のコードを読む