これは purescriptアドベントカレンダー2014年の2日目です。
昨日は purescript-react を動かしてみるまで頑張る でした
purescript自体の紹介はいいですね。一言でいうと、Haskellっぽい(けどHaskellと直接互換性はない)関数型なAltJSです。
ライブラリというと、まず最初に見るべきリポジトリというかorganizationとして以下の2つがあります。
というか、個人的にそれ以外あまり知りません。この2つでも、それなりな量あるので、アドベントカレンダーで紹介するには十分でしょう。そして、purescript-contribのほうは手がまわらないので別の機会に・・・(もしくは誰か紹介してくれていいですよ)
なお、あくまでもコレを書いている2014年12月2日時点の情報です。できたばかりの言語で、かなり開発活発なので、すぐに古くなる可能性ありますが、そのあたりご了承ください。
では早速どんどん紹介していきましょう。特に紹介順に意味はありません。
https://github.com/purescript/purescript-free
freeといえばそうですね、みんな大好きfreeモナドです。単にfreeモナドだけでなく
- Coyoneda
- Yoneda
- Trampoline
- Cofree
- MonadFree
なども入っています。Coyonedaあるし、Operational Monadも普通にできるでしょう。というか、それ用に(Scalazと同じく) type FreeC とか定義されてます
https://github.com/purescript/purescript-enums
実質1ファイルしかないです。まったく同じではないけど、HaskellのEnumに近いものだと思います。特徴として
- 順番を保持
- なので、次の要素、前の要素、の取得関数がある
- 要素数がNumberで取得できるようなので、有限の決められた個数?
- Numberとの相互変換の関数が用意されている
https://github.com/purescript/purescript-tuples
Tupleです。Tupleが標準じゃなく、外部ライブラリというのは、結構変わってますね?
おそらく、Tupleが(Row Polymorphismなどにより?)あまり必要にならないので、外部ライブラリなのでしょうかね?
https://github.com/purescript/purescript
コンパイラと標準ライブラリ本体。ここの説明は今回はしない
https://github.com/purescript/purescript-arrays
いわゆる普通のArrayとSTArrayのようです。purescriptでどういうデータ構造使うのが一般的なのかよくわかってないので、そのうちちゃんと調べたい・・・
https://github.com/purescript/purescript-strings
Stirngに関するユーティリティや、正規表現関連。
このくらいのものなら、標準ライブラリに入っていてもいいような気もしますが・・・。purescriptはなんだか細かく外部ライブラリに分ける傾向がある気がします。
https://github.com/purescript/purescript-quickcheck
QuickCheckというHaskellのテストライブラリの移植です。大雑把に眺めた感じ、まだそれほどコード量多くなくて、機能足りない部分もありそうですが、sampleもあったし普通に使えそうです。
https://github.com/purescript/purescript-refs
説明に"Mutable value references"とあります。それ以上でもそれ以下でもなさそうです。コードもかなり少ないです。HaskellだとIORefとかに相当するようなものでしょうかね?
https://github.com/purescript/purescript-foldable-traversable
リポジトリ名のとおり
- Foldable
- Traversable
という、わりと有名な型クラスです。これも標準じゃなく外部ライブラリなんですね(標準に入っていて欲しい気もする・・・)
以前ここに、Foldable1とTraversable1を入れてpull reqしようとしたけど、purescript力がなくて断念しました。今もまだ入ってないようです。誰か入れてくれ・・・
https://github.com/purescript/purescript-foreign
Foreignて、つまりJavaScriptの世界とやりとりするときのための、便利なユーティリティ集といった感じでしょうか
https://github.com/purescript/purescript-lazy
"Call-by-need values" という説明があります。Haskellと違いpurescriptはlazyではないので、そういうことをしたい場合、専用のデータ構造作る必要があります。そのあたりはScalaと同じですね。
コレを書いている時点では、Lazyというデータ構造と、それを使ったLazyなListのみがあるようです
https://github.com/purescript/purescript-bifunctors
説明に "Bifunctor, Biapplicative, Bifoldable, Bitraversable" とあり、それで言い尽くされてますね。EitherとかTupleみたいに、型パラメータを2つとるものがインスタンスになったりするやつです。
それほど頻繁に使う型クラスでもないですが、かといって使いたくなったときに一からつくるのも微妙なので、このレベルの型クラスでも、こうしてちゃんとライブラリになってるのは嬉しいですね。
https://github.com/purescript/purescript-transformers
これは・・・結構盛りだくさんな感じがありますね。HaskellでいうとMTLとかそのあたりのやつ?大雑把に眺めた感じでは
- Writer, WriterT
- State, StateT
- Reader, ReaderT
- RWS (ReaderWriterState)
- Error
- MonadTrans
- MaybeT
- MonadError
- ContT
- Traced, TracedT
- ComonadTrans
- ComonadStore
- StoreT, Store
- ComonadEnv
などなど。Monad系だけではなく、Comonad系のやつも全部含まれてるようですね。なぜこれだけ大きいのか
https://github.com/purescript/purescript-maps
データ構造としてのimmutableなMapです。現状の実装は
https://github.com/purescript/purescript-maps/blob/27991cb7c13f3e41f149057d58049a977ac6aff8/src/Data/Map.purs#L4
Maps as balanced 2-3 trees
Based on http://www.cs.princeton.edu/~dpw/courses/cos326-12/ass/2-3-trees.pdf
とありました。こういった関数型のデータ構造の翻訳は、まだ足りてない気がする?から、contributeのチャンスかも?
あと、JavaScriptとして動く関係上、KeyがStringなMapは速くできる余地がある?ということで、StrMapというKeyがStringのMapが別にあるようです
https://github.com/purescript/purescript-globals
isNaNとかの、JavaScript上の特殊なグローバル関数を呼び出すだけのもの?すごくソースコード少ない
https://github.com/purescript/purescript-exceptions
JavaScriptの世界の例外といい感じにやりとりするためのものみたいです。
purescript内で完結するものには使う必要なさそう(そういう場合はEitherや、さきほどのpurescript-transformersのものを使えばよさそう)
https://github.com/purescript/purescript-distributive
Distributiveという、それほど有名じゃないけど、ekmettライブラリやScalazにも存在する型クラスです
https://github.com/purescript/purescript-control
Apply, Bind, Functor, Extend, Monad, MonadPlus, Plus, Alt, Alternative などの、超基本となる型クラス達です。Haskellと違って、このあたりが綺麗な継承関係でまとまってるのはよいですね。
あれ、このあたりって標準ライブラリの一部だった気もするけど、今どうなってて、今後どうなるんだろう・・・。あとで気が向いたら、調べよう・・・
https://github.com/purescript/purescript-exists
説明には "Existential types as a library" とあります。なるほどそんなことができるんですか!?
ソースみたら、すごく少なくて、foreignをうまく使ってどうにかしてるようです?
ある意味、purescript自体は関数型だけど、JSという型が緩いものの上に載ってるのでこういうことが簡単に作れてしまう、のは、JVM(という. NETのVMとは違うtype erasureなもの)の上に載ってるおかげで色々できるScalaと近いものを感じます
https://github.com/purescript/purescript-either
Eitherまで別ライブラリなの・・・
https://github.com/purescript/purescript-profunctors
ある程度のレベルのHaskellerなら知ってるであろう、Profunctorです。ArrowとかCategoryなどの関連するclassは含まれてないようです。(それらはどこにあるのだろう・・・)arrowなどはこっち https://github.com/purescript-contrib/purescript-arrows にありました
https://github.com/purescript/purescript-contravariant
これも、名前の通り、contravariantという型クラスのみが入ってるライブラリです
https://github.com/purescript/purescript-maybe/blob/master/src/Data/Maybe.purs
言わずと知れたMaybeですね。それしか入ってません。何度も言ってますが、ライブラリ細かく分けすぎじゃないですかね・・・。最終的なJSの出力サイズ小さくするためには、細かくなっていたほうがよい、という判断なのかな?
https://github.com/purescript/purescript-monoid
いろんなMonoid。いろんな、とはBooleanは&&や||でそれぞれ違ったMonoidになるし、FunctionはEndoとかあるし、MaybeはFirstやLastといったいくつかの形でMonoidになる、などです
https://github.com/purescript/purescript-validation
ScalazのValidationと大体同じもの
以上、だいぶ雑な紹介でした。purescriptのorganizationのものさえも全部紹介しきれてません、すいません。
このようにHaskellやScalaz知ってる人にとっては、大体知ってるものがあるので、そういう点では入りやすいと思います。ただまだ足りてない部分もありそうなので、貢献していきたいですね。
次の3日目は 実例で学ぶ purescript ライブラリの開発 です