purescriptのライブラリ紹介

これは 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ファイルしかないです。まったく同じではないけど、HaskellEnumに近いものだと思います。特徴として

  • 順番を保持
  • なので、次の要素、前の要素、の取得関数がある
  • 素数が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 ライブラリの開発 です