この記事は (bouzuya) PureScript Advent Calendar 2016 の 22 日目。 (bouzuya) PureScript Advent Calendar 2016 は bouzuya の PureScript 学習の記録だ。
- ← 21 日目『 PureScript by Example の 6.5, 6.6 を読む - Qiita 』
- → 23 日目『 PureScript by Example の 6.11, 6.12, 6.13 を読む - Qiita 』
概要
PureScript by Example を PureScript Language Guide や Pursuit を見ながら進めていく。
今日は 6.7 を読む。ソースコードの例は purescript-book の exercises/chapter6 にある。
※注意事項: 英語と日本語訳では大きな差異がある。0.10.x
に対応している英語の側で進める。
- PureScript by Example 2016-12-05 時点で 0.10.x 向け
- 実例による PureScript 2016-12-05 時点で 0.7 向け
- PureScript Language Guide 対象バージョン不明
この章のおさらい
この章では型クラス (type classes) を扱うらしい。
class
/ instance
キーワードおよび型クラス Show
/ Eq
/ Ord
/ Field
/ Semigroup
/ Monoid
/ Foldable
/ Functor
を見た。必要に応じて ::
演算子で型を指定する方法、関数への型注釈 (type annotation) やインスタンスの重複ができないことも見た。
Pursuit:
- Data.Show - purescript-prelude - Pursuit
- Data.Eq - purescript-prelude - Pursuit
- Data.Ord - purescript-prelude - Pursuit
- Data.Field - purescript-prelude - Pursuit
- Data.Semigroup - purescript-prelude - Pursuit
- Data.Monoid - purescript-monoid - Pursuit
- Data.Foldable - purescript-foldable-traversable - Pursuit
- Data.Functor - purescript-prelude - Pursuit
- Data.Maybe - purescript-maybe - Pursuit
PureScript by Example 6.7
インスタンスの依存関係。インスタンスが他の型クラスのインスタンスに依存できる。 =>
を instance
でも使えるという話。
PureScript by Example 6.8
型変数を複数持つ型クラス。 0 個以上の任意の個数なので、複数でも問題ないという話。 PureScript by Example では Stream list element
という型クラスを定義している。よく見るものとしては Either
などもその例だろう。
Pursuit:
PureScript by Example 6.9
関数従属性 ? (functional dependency) 。日本語訳 (0.7.x) にはなくて、訳語がよく分からない。 RDBMS における関数従属性を functional dependency と呼ぶっぽいし、それと似たような意味合いで使っていそうなので、関数従属性と呼ぶことにする。
複数の型変数を取る型クラスを使うと、容易に推論できない関数を書けてしまう。型変数間の関係を記述することによってエラーを減らせる……という話っぽい。以下は PureScript by Example からの例。
class Stream stream element | stream -> element where
uncons :: stream -> Maybe { head :: element, tail :: stream }
| stream -> element
の部分がそれらしい。 stream
が決まれば element
は一意に決まることを教えてあげると、と。
どれくらい使う機能なのかは想像できない。
PureScript by Example 6.10
今度は型変数のない型クラス。
Partial
が例に挙げられている。以前 unsafePartial
の話をしたときに出てきたものだ。
部分関数に対して (Partial) =>
と型注釈をつけることで、それを相手に確認させることができる。
purescript-arrays
の Data.Array.Partial
の head
はその例だ。
> import Data.Array.Partial (head)
> head [1, 2, 3]
Error found:
in module $PSCI
No type class instance was found for
Prim.Partial
while checking that expression eval it
has type Eff t0 t1
while applying a function eval
of type forall a.
(Eval a) => a
-> Eff
( console :: CONSOLE
)
Unit
to argument it
in value declaration $main
where t0 is an unknown type
t1 is an unknown type
See https://github.com/purescript/purescript/wiki/Error-Code-NoInstanceFound for more information,
or to contribute content related to this error.
unsafePartial
すれば Partial
を外すことができる。Partial
な関数を呼び出す関数を Partial
にすれば、回避せずに済む。
ちなみに head
は Data.Array
にあるものを使えば Maybe
が返される。
Pursuit:
- head - Data.Array.Partial - purescript-arrays - Pursuit
- unsafePartial - Partial.Unsafe - purescript-partial - Pursuit
まとめ
型クラスの型変数が 0 個の場合や複数個の場合を見た。型変数間の関係の記述についても見た。
Partial
は意外と出てきそうだ。
次回以降の TODO
- PureScript by Example & PureScript Language Guide を読み進める
-
Array
以外でのdo
記法 psc-package
- 24 Days of PureScript, 2016
- 24 Days of PureScript, 2014
- 某氏の記事の紹介
- github.com/purescript のコードを読む
- github.com/purescript-node のコードを読む
- github.com/purescript-contrib のコードを読む