2011年12月25日日曜日

Kleisli

Kleisliを忘れてました。

Kleisli

Kleisliはある入力をとり、出力をコンテナで包むものです。
Scalazの例でよく出てくる☆はこいつです。


Kleisliの合成には、>=>と<=<があります。


Function1W#kleisliは結果をコンテナで包むKleisliをつくります。


Kleislis#askはKleisliにおける恒等関数をつくります。


その他のメソッド


  • =<<
    • コンテナの要素をKleisliに適用
  • compose
    •  出力のコンテナを変える。
  • traverse
    • 要素をコンテナで包む。

KleisliはA => M[B]の形の関数で、合成ができて、☆という印象。
scalaz.httpの資料で、routingにKleisliを使っています。
"scalaz http kleisli"でググるとでてきます。

2011年12月24日土曜日

State, StateT

クリスマスイブらしいよ!
私は家で引きこもってるけど!
State

状態を保持する計算に用いられます。


Stateは!で値を、~>で状態を、applyで両方をとりだせます。
値、状態を取り出すときには、初期状態を与えなければなりません。



値や状態を操作するための関数はStatesに定義されています。

init

状態で値を初期化します。

put

状態を上書きします。

gets

状態から値を更新します。

modify

状態から状態を更新します。

state

状態から値と状態を更新します。


IdentityにもStateを作る関数が定義されています。

state

呼び出し元を初期値にします。

constantState

呼び出し元を初期値にし、初期状態を与えます。


State#withsは入力される状態を更新します。


StateT


モナド変換子版もあります。


mapsにより別のモナドにmapすることもできます。


Writerは結合していくことしか出来ませんでしたが、Stateではもう少し自由度が高いというイメージです。
ScalaはvarがあるからStateモナドとかいらないのでは?と思っていましたが、実際に調べて書いてみると可変な参照とはまた違ったもので、これはこれで使い方がありそうです。
STモナドはいりません。

2011年12月23日金曜日

Writer, WriterT

Identity, MA, MABで使う型クラスはほとんど書いたので、モナドを書いていこうと思います。

Writer

計算中の値とは別にもう1つログを作ります。


値とログはoverとwrittenで取り出せます。


Writers#writerで直接インスタンスを作ることも出来ます。


WriterT

Writerのモナド変換子バージョン。


WriterTに定義してある型クラスのインスタンスは全て[α]WriterT[M, W, α]となっているので、BindやFunctorのインスタンスを利用するには、型の別名が必要みたいです。
put, putWithの他に、liftw, liftwWith, writerTがあります。


Writerは使えそうだけど使い方がわからないモナドの一つでしたが、モナド変換子の使い方もわかったし、これからはロジックの中に組み込んでいけそうです。

Foldable

冬休み入ったのでのびのびひきこもりたいとおもいます。

Foldable

畳み込み関数を持ちます。
最低限実装しなければならないものはfoldRightかfoldMapです。

MA#foldMap

foldMapは要素をMonoidへ変換し、結合します。


MA#foldr, MA#foldl

右畳み込みと左畳み込み。


MA#foldl1, MA#foldr1

foldの初期値をなくしたもの。
失敗した場合はNoneが返る。


MA#foldLeftM, MA#foldRightM

モナドに包み、合成します。


MA#all, MA#∀, MA#any, MA#∃, MA#element, MA#∋, MA#∈:

allとanyは述語を、elementは要素を渡します。
∀, ∃, ∋, ∈:はエイリアスです。


MA#empty, MA#count, MA#foldIndex

emptyは空かどうか、countは要素の数、foldIndexはインデックスの値を取得します。
foldIndexは失敗した場合例外を投げます。


MA#listl, MA#listr, MA#stream

listl, listrはListに、streamはStreamにまとめます。
listlはfoldlで、listrはfoldrで実装されています。


MA#maximum, MA#minimum

要素の中から最大値、最小値を取得します。
要素が存在しない場合、Noneが返ります。


MA#selectSplit, MA#splitWith

selectSplitは述語が真の連続する要素を集めます。
偽の要素は捨てられます。

splitWithは述語が真か偽に変わるまで要素を集めます。


畳み込み関数は汎用性が高いのでFoldableが定義されるだけでこれだけの関数が使えるようになります。
前に紹介したTraverseは畳み込み関数が定義されていると定義がしやすかったのですが、Foldableは継承されていません。
しかし、Scalaz7ではTraverseがFoldableを継承するように変更されています。

2011年12月22日木曜日

Reducer, Generator

昨日は #rpscala の忘年会がありました。
技術的な話がいっぱいで楽しかったです。
私も頑張らねば・・・!

Reducer

ある型CをMonoidである型Mへとマッピングするものです。

Identity#unit

値をモノイドへ変換します。


Identity#cons, Identity#snoc

値と、モノイドである値を結合します。


Identity#unitPure

モノイドへ変換した後、値を包みます。


MA#foldReduce

指定した型にまとめます。


Generator

Reducerを使ってコンテナの要素をまとめます。

GeneratorオブジェクトにはGeneratorのインスタンスが定義されており、Generator#reduceの実装が違います。

Generator#toとGenerator#fromはReducerと初期値とコンテナを渡します。
Generator#reduceはZeroが初期値となります。


Reducerのインスタンスはデフォルトでimplicit parameterではないので、いちいち宣言しないといけません。
unitやconsは普通に使える関数なだけに、とてももったいなく感じます。
しかし、Scalaz7では全てimplicitになっているので、Reducer関連の関数は使いやすくなるだろうと思います。

2011年12月20日火曜日

Category, Endo, Dual

Category

けんろん!

圏論の基礎を読んでいるのですが高校数学では太刀打ち出来ませぬ。

Categoryはcompose(合成関数)、id(恒等関数)を持ちます。

MAB#>>>, MAB#<<<, MAB#⋙, MAB#⋘

(f >>> g).apply(x)はg(f(x))、(f <<< g)(x)はf(g(x))と同じです。

⋙は>>>の、⋘は<<<のエイリアスです。


Endo

Endomorphismと言うらしい?
早く可換図に書いてあることがわかるようになりたいですね・・・

EndoはA => AのNewType。
つまり、入力と出力が同じ関数です。

Function1W#endo

Function1[A, A]をEndo[A]に変換します。


EndoはMonoidで、|+|は関数合成、mzeroは恒等関数が返ります。

Dual

そうつい!

DualはMonidで、結合時に左辺と右辺を入れ替えます。

Identity#dual,  Identity#σ

dualはDualのインスタンスを返します。
σはdualのエイリアスです。


Dualがとる型はMonoidに限りませんが、今のところMonoid以外で特殊な動きはしません。

今回はCategoryはあまり深くまで調べませんでしたが、Categoryオブジェクトをみると意味不明用途不明なものがたくさんあります。
使い道などがわかったら是非教えて下さい!

2011年12月19日月曜日

IterV, Enumerator

一昨日Pythonでも書いたので書いておく。

IterV

IterVはIterateeです。
ストリームをイテレートするものと考えて下さい。
ストリームを表すものとしてEnumeratorが定義されています。

IterV#applyによりEnumeratorをイテレートし、IterV#runで実行されます。


Enumerator#applyはコンテナとIterVをとり、コンテナをイテレートする関数が定義されます。

IterV#foldは、計算が終了した場合は結果と入力をとり、計算が途中の場合は入力から次の計算を取り出す関数をとり、何らかの値を返します。

入力にはEmpty, El, EOFがあり、それぞれデータなし、データあり、データの終わりを表します。

IterVには標準でいくつかの操作が定義されています。

IterV.head

ストリームを消費して、先頭要素をOptionで返します。

IterV.peek

先頭要素を返します。
こちらはストリームを消費しません。

IterV.length

ストリームの長さを取得します。

IterV.drop

指定した数だけストリームを消費します。

IterV.collect

指定した型に変換します。

IterV.groupBy

先頭要素と各要素をとる述語が真である限り、要素を集めます。

IterV.takeWhile

述語が真のあいだ、要素を集めます。

IterV.reversed

要素の順序を逆にしたコンテナを返します。

IterV.repeat

Iterateeを繰り返し、結果を集めます。


そして、Iterateeは合成が可能です。


scalaz.effectsパッケージではIterateeを使った入力ストリームがあります。
あまり詳しく書いていませんが、Scalaz.effectsについてを書いたので興味があったら見てください。

いまではWeb FrameworkのPlay!にも存在します。
http://playframework.github.com/api/scala/#play.api.libs.iteratee.package
今後の入出力操作の標準となるかもしれないので勉強しておいて損はないはずです。

2011年12月18日日曜日

Digit

漢数字パーサをゴルフしてたので今日はDigit。

Digit

数字を表します。
Digitオブジェクトにこれを継承した0から9までの数字が定義されています。

toInt, toChar, toLong


Digits

DigitsにはdigitsとLongからDigit、DigitからLongへ変換するimplicit conversionが定義されています。

digitsは_0から_9までをもつListです。


MA#digits, MA#traverseDigits, MA#longDigits

digitsはコンテナが内包するCharをDigitへ変換します。
変換に成功した場合はSome、失敗の場合はNoneが返されます。

traverseDigitsは成功した場合、コンテナがSomeで包まれます。

longDigitsは内包されたDigitをLongへ畳み込みます。
この時先頭の0は無視されます。


最後にたかはしさんからforkしたコード。


ただDigitを使ってみたかっただけ。
数をListとして操作できるのも面白いなと思いました。

Memo

Memo

メモ化!

恒例のフィボナッチ数列を書いてみる。


メモ化してみる。


m(fib)はMemo#applyが呼ばれ、メモ化された関数が返ります。
!fibはFunction1Wに暗黙の型変換され、unary_!が呼ばれています。
unary_!は暗黙のパラメータでMemoをとり、メモ化します。

実装をメモ化する。


Memoには標準でいくつかの実装が用意されおり、Memosに定義されています。

memo関数により自分で定義することもできます。

2011年12月17日土曜日

Python Iteratee

Python mini Hack-a-thon

参加しました。

今日はPythonでIterateeを書きました。

IterateeはIOストリームを抽象的に扱うもの・・・らしい。
composableでおもしろいなー
とちょっとした興味でさわってるのでそこまで詳しい訳じゃないです。

とりあえずソースコード。





これで何が嬉しいかというと
  • 処理が合成できる
  • IOストリームだけでなくリストなども処理できる
他にもハイパフォーマンスで型安全という特徴があるらしいのですが、この実装だと遅いし、Pythonだと型安全とか意味をなさないのであまり旨味がないかなあと思いました。

Traverse

Traverse

今日はなんだか複雑な型クラスTraverse。
Functorを継承しています。

traverseという関数をもちます。


たぶんこれを見ても内部でどういったことをしているかわからないと思います。

sequence

Haskellのsequence関数を知っていますか?


Haskellのコードを見てもわからないのでScalaで書き直してみます。


というかこれMonadである必要はなくね!?
と気付いた方、さすがです。
Applicativeで十分なので書き直してみます。


実はこのsequence関数はScalazでも定義されています。
これはより汎用的なものでListのみではなく、Traverseのインスタンスを持つものならば利用可能です。
そしてこの関数は、traverse関数に恒等関数を渡すことで実装できます。


これらのことからtraverseはコンテナT[A]の要素Aを関数A => F[B]に適用してT[F[B]]になったものを畳み込み関数とApplicativeのapplyメソッドでF[T[B]]に変換する関数ということが・・・・・わかりにくいですよね、説明力なくてすみません・・・・・

実際には、畳み込み関数が使われているかどうかはTraverseのインスタンスの実装によって変わってきます。

Traverseの本質などは偉い人に聞いてもらうとして、ここではTraverseを使った関数を紹介します。

foldMapDefault

foldMapのTraverse実装。


collapse

sumのTraverse実装。


zipWithA

2つの値をコンテナにまとめてsequence。


今回も説明がわかりにくくてごめんなさい。
ここで出てきたfoldr, foldMap, sumは近々書くので今日のところはこれでひとまずおわりです。

2011年12月15日木曜日

Empty, Each, Plus

小粒な型クラスその2

Empty

空を定義します。

<∅>

コンテナの型と要素の型を渡し、空のコンテナを返します。
∅が打ちにくい。


Each

繰り返し処理を定義します。

foreach, |>|

関数を渡し、処理を繰り返します。
|>|はforeachのエイリアスです。


Plus

plusという2つの値を結合する関数を持つ。
Semigroupよりも、短絡評価ORの性質が強い。

<+>, <+>:

<+> は2つのコンテナを結合します。
<+>: は要素の型にPureのインスタンスが必要で、要素を渡して包み、結合します。


今回紹介した型クラスは関数がそこまで多くないのであまり自分で定義することはないだろうけど、定義されたものを使う分にはとても便利です。

Length, Index

今日は小粒な型クラスを書いていきます。

Length

長さを定義します。

len

長さを返します。


Index

インデックスを定義します。

index, index_!, -!-

n番目の値を返します。
indexはOptionで返り、index_!はそのまま返ります。
-!-はindex_!のエイリアスです。


<--->

Length, Index, Equalのインスタンスがある場合に利用できます。
互いが内包する要素の間で、異なる要素の数を返します。


ペースを保つためその2へ続く。

2011年12月14日水曜日

Monad

朝、親に電車代を交渉し忘れて rpscala にいけないという・・・・・

今日はMonad。

Monad

Monadが何たるかは

モナドは象だ

を読みましょう!(まるなげ

モナドなんて高階関数を持ってて結合可能なコンテナぐらいの認識でいいのです!(ぼうろん

ここではScalazでMonadに関連する関数を紹介します。

Monadのインスタンスを直接定義するか、BindとPureのインスタンスが定義されていればimplicit parameterにMonadのインスタンスが供給されます。


getOrElseM

値Mに包まれたOption[A]がSomeの場合、値を返し、Noneの場合呼び出し側を返します。


ifM

trueの場合とfalseの場合で値を振り分けます。


replicateM

型パラメータを1つとる型と繰り返す回数を渡し、包まれた値を連結します。


foldLeftM, foldRightM

普通のfoldと違い、包まれた値を返す関数を渡します。


Scalaではあるクラスを実装するのではなく、flatMapとmapさえ実装されていればfor式が使えちゃう。
for式はflatMapがネストしたら使えばいいんじゃなイカ?

2011年12月13日火曜日

Applicative, ApplicativeBuilder

#expertpython に行く予定でしたが池袋駅で目黒へ行くお金すらなかったことに気づいて泣く泣く帰ることに・・・・・
鬱々ですが明日も頑張ります。

今日はApplicative。

Applicative

ApplicativeはApplyとPointedを継承します。
基本的にApplyはFunctorや、Pureと組み合わせて使うのでApplicativeのインスタンスであるといろいろな関数が使えるようになります。


Pointed

FunctorとPureを継承しています。
Applicative, Monadがこれを継承します。

Applicativeスタイル

forでは


と書けますが、Applicativeスタイルでは


と書けます。

この書き方では、関数がカリー化されている必要があります。
<**>, <***>, <****>, <*****>を使うとカリー化の必要がなくなり、適用の順番が綺麗に書けます。



ApplicativeBuilder

これらの書き方以外にApplicativeBuilderを使ったものがあります。


このようにApplicativeは値をコンテナから取り出して関数にてきようするものです。
for yieldであの形になったのなら、Applicativeスタイルで書けるということをおぼえておけばいいのだと思います。

2011年12月12日月曜日

NonEmptyList, Validation

昨日までMonadへ向けて型クラスをつらつら書いていましたが、Scalazのデータ構造にも触れたいと思います。

NonEmptyList

名の通りの空じゃないリストです。

利点は
  • head,tailで必ず値が返ることが保証される
  • reduceも必ず成功する・・・のだがそれにあたるメソッドはない。
と、これぐらいしか浮かばないけれど空を許さないという性質は意外と便利であったりします。


wrapNelは値をNonEmptyListで包みます。
nelはNonEmptyListのインスタンスを作ります。
<::は値を先頭に追加。
<:::, :::>はListをNonEmptyListに連結します。

ただ残念なところは、せっかくheadやtailが成功するのに、分解するためのunapply, unapplySeqが定義されていないことです。

ScalazではValidationと併せて使われます。

Validation

Validationはエラーか値を返すための直和型です。
Eitherとの違いはエラーをaccumulateできるところです。

解説、考察などは

http://d.hatena.ne.jp/xuwei/20110927/1317156625
http://d.hatena.ne.jp/cooldaemon/20111017/1318862426
http://d.hatena.ne.jp/terazzo/20111022/1319295098

に書いてあってあまり書くことない・・・

のでとりあえず関係するものを挙げていきます。

ValidationNEL

Validation[NonEmptyList[E], A]のエイリアスです。
Scalazオブジェクトに定義されています。

success, fail, successNel, failNel

Success, Failureで値を包みます。


parse{Boolean,Byte,Short,Int,Long,Float,Double}

StringWに定義されている関数。
パースに失敗したらNumberFormatExceptionをValidationで返します。


Validation#failはFailProjectionというError値を操作するためのコンテナを返します。
Eitherの場合はRightProjection, LeftProjectionとありますが、ValidationはデフォルトでSuccessに対して操作をするので、FailProjectionだけが存在します。
FailProjection#validationはもとのValidationを返します。


lift, liftFailNel

持ち上げ関数。
liftは値をwrap、liftFailNelはエラーをNonEmptyListでwrapします。


|, |||

| は失敗していたときに渡した値が返ります。getOrElseのようなもの。
||| は失敗していたときは、そのエラーの値をとり、成功時の型で値を返します。


Validation、とってもいいですよ!
最近、エラー処理を書いてはいけないというスライドが上がっていました。
アレほど強力ではないですが、エラーをaccumulateしていけるということはやはり便利だと思います。

2011年12月11日日曜日

Apply

一昨日の分書いてない、昨日の分書いてない、今日の分書いてない・・・・・
そしてどんどん難しくなっていくScalazネタ。
実際危ない!

Apply

Applyは名の通り適用のための型クラスです。
しかし、ただ関数に値を適用するものではなく、コンテナ内の関数にコンテナ内の値を適用します。


FunctorBindApplyはApplysに定義されています。
FunctorとBindを暗黙的にとり、Applyを返します。

<*>, <**>, <***>, <****>, <*****>

Functorではmap、Bindでは>>=と代表する関数がありますが、Applyでは<*>です。
これは<*>の場合は先程の例の通りですが、<**>からはコンテナと関数、implicit parameterにFunctorをとります。
*が増えるごとに、コンテナの数、関数の引数が増えていきます。
ただし、値がNilやNone, Leftなどが含まれている場合はその値が返ります。


<|*|>, <|**|>, <|***|>, <|****|>

コンテナをわたし、コンテナに包まれたタプルを返します。
ただし、値がNilやNone, Leftなどが含まれている場合はその値が返ります。


*>, <*

>, <が指す値を返します。
ただし、値がNilやNone, Leftなどが含まれている場合はその値が返ります。


コピーアンドペースト重点。

これらの関数は型により動作が変わりますが、大体の型はこのような動きをします。

第二回Scala会議

第二回Scala会議に参加し、Scalazについて発表しました。

資料
http://halcat0x15a.github.com/slide/scala_kaigi/out/index.html


いつも通り緊張で死にそうになりながらみずしまさんとゆろよろさんに助けられつつの発表でした。
たまきさんの気遣いにも感謝です。

自分の発表能力はまだまだ低く、もっと練習して行かなければいけないと感じます。

懇親会では技術的な話をたくさん聴けて楽しかったです。
いつも支払いをしていただいて、 高校生な自分としては本当に助かります。
技術的なアウトプットを増やしていって、少しでも応えられたらなと思います。

2011年12月8日木曜日

Bind

昨日は rpscala へ行ってきました。
直接感想等をもらえてうれしかったです。
いつも御世話になっている皆さんに少しでも役に立つようがんばります。

Bind

今日はBindです。
Bindは型Z[_]を型パラメータにとり、型Z[A]と関数A => Z[B]を受け取り、Z[B]を返す関数bindを持ちます。
Haskellでは>>=にあたります。


この例ではScalaChanFunctorとScalaChanBindを定義し、 MAに定義されたmap,flatMapが使えるようになったかを確認しました。

flatMap, >>=, >>=|, >|>

flatMapと>>=は同じ関数です。
>>=|と>|>も同じ関数です。
>>=|, >|> はflatMap, >>=と違い、内包していた値を捨て、値だけを渡します。


ちなみにflatMap, >>=の糖衣関数∗、>>=|, >|>の糖衣関数∗|が定義されています。

forever

使い方がよく分からない関数。
>|> を使い、foreverの結果を連結し続けます。
なので評価するとStackOverflowError必至だと思うのですが・・・


join

型M[A]のAに、M[A]が適用されたM[M[A]]を連結し、M[A]を返します。
要は汎用的flatten。
糖衣関数にμがあります。


最後の例はjoinを行ったことにより、

(\a. (\b. a + b))




(\a. (\b. b)(a) + a)

に変換されました。

値を適用すると、

(\a. (\b. a + b))(5)(5) ->
(\b. 5 + b)(5) ->
5 + 5 -> 10

(\a. (\b. b)(a) + a)(5)
(\b. b)(5) + 5
5 + 5 -> 10

となり、関数に値を2度適用する関数であることが分かります。

Bindはbindという1つの関数だけを持っていますが、それを定義するだけでこれだけのものが使えるようになります。

Scalazおそるべし・・・・!


2011年12月7日水曜日

Functor

Pure, Functor, Pointed, Apply, Applicative, Bindを倒さないとMonadへはたどり着けない・・・・・

ということでFunctorの紹介。

Functor

Pureと同じように型パラメータを1つとる型を型パラメータにとります。

fmapというコレクションでおなじみのmapと似た関数を持っています。

mapと違うところは要素を包む型が多相であるというところです。


Identity

mapply

値を内包された関数に適用します。


MA

map, map2, >|

mapは関数を渡し、内包する値に適用します。
map2はFunctorがネストしている場合に利用でき、ma.map(_.map(f))と等価です。
>| は値を渡し、その値で塗りつぶします。


fpair, fpure

fpairは内包された値のペアを作ります。
fpureは内包された値を指定した型で包みます。


comp

Option[List[Int]]をMA[M[_], A]とみなすとき、MにOptionが、AにList[Int]が適用されMA[Option, List[Int]]となります。
compではMにOption[List[_]]を、AにIntを適用したMA[({ type X[A] = Option[List[A]] })#X, Int]を返します。
MAの型としては型の部分適用されたものが返るので普通の型クラスは対応していません。
しかしCompをインポートすることでApplicativeとFunctorのimplicit valueを得ることができます。


InvariantFunctor

FunctorはInvatiantFunctorを継承しています。 

MA

xmap

一度別の型に変換し、また元の型へ変換します。


Semigroup以外に、Endo, Monoid, Memoのインスタンスが定義されています。

xmapはともかく、mapやmap2,compは使いどころが多いと思います。
積極的に使っていってコードをScalazで染め上げましょう!

2011年12月6日火曜日

Pure

Scalazはモナモナしたデータ構造が多いので早くMonadところまでやりたい・・・

ということで今日はPureを書きます。

Pure

Pureは"型パラメータを1つとる型"を型パラメータにとり、値を包み込む関数を持ちます。

分かりにくいので例を挙げます。


Pureを利用した関数では、計算をして結果を包むものが多いです。

pure

型を渡し、値をその型で包みます。


iterate, repeat, replicate

iterate, repeatは無限リストなんかを作る関数。
Stream以外に使えるものはあるのだろうか?

replicateはiterate, repeatと似ているけれど、大きさが決まっています。
これはListなどでも使えます。


+>:

値を包み込み、結合する演算子。
使い方がよくわからず、 List(1).+>:(1) とか書いてたけど : がついてるとレシーバが右にくるとの御指摘が。
演算子の結合順位もよくわかっていないのでコップ本を読み直さないとですね・・・


MA

今回の関数は +>: 以外Identityに定義されています。
+>: はどこに定義されているのかというと、MAに定義されています。

MAは"型パラメータを1つとる型"Mと型Aを型パラメータにとります。


Scalaではイレイジャで型M[A]の型Aが消えてしまうため、このような定義になっています。

このMAでは、"型パラメータを1つとる型"を対象にした型クラスを利用する関数が定義されています。

今後紹介する関数では、Identity,MAそしてMABで定義されたものを中心に紹介していきます。

これらはScalaz特有の関数を利用するための型クラスなので深い理解はいりませんが、Scalazを使う上で覚えておいて損はないでしょう。

2011年12月4日日曜日

Semigroup, Zero, Monoid

今日はSemigroupでゲソ!

この記事は

Functional Ikamusume Advent Calendar jp 2011



一人Scalaz Advent Calendar

を兼ねているんじゃなイカ!?


Semigroup

Semigroupは結合可能という性質を表すでゲソ。

Semigroupは関数 def append(s1: S, s2: => S): S を持ち、2つの値から一つの結果を得る関数を持つでゲソ。

Semigroupのインスタンスはsemigroup関数を使うことで定義できるんじゃなイカ?

Semigroups#semigroup


Semigroupを利用する関数

|+|

加算だけでなく、型によって様々な動きをするでゲソ。


加算や連結、論理和のような動きをするでゲソ。
===と同様に型安全でもあるでゲソ!

・・・・・Semigroup単体だとこれだけでゲソ。

あまりにも寂しいのでZero, Monoidまでやろうじゃなイカ!

Zero

Zeroは単位元を表すでゲソ。

mzero

mzeroは型パラメータを取り、その型の単位元を返すでゲソ。

matchOrZero

matchOrZeroは型パラメータとPartialFunctionを取り、マッチしない場合はその型の単位元を返すでゲソ!


Zeros#zero

Zeroのインスタンスはzeroにより定義できるんじゃなイカ?


そして、SemigroupとZeroを兼ね備えたものがMonoidなのでゲソ!

Monoid

MonoidはSemigroupとZeroを継承したものでゲソ。

Monoidは

forall a. append(zero, a) == a

forall a. append(a, zero) == a

を満たすのでゲソ。


イカ娘も立派なモノイドじゃなイカ?

Monoid単体を利用する関数はほとんどないのでゲソ。
Monoidは他の型クラスと一緒に使うことが多いのでその時に紹介しようじゃなイカ!

Order, Ordering

OrderOrderingについて。

OrderはEqualを継承しており、比較を可能にします。

Scala標準のAPIにもOrdered, Orderingがありますが、これらはJavaのComparableのように正、零、負で表しています。

しかし、このOrderでは比較結果をOrderingという型で返します。

?|?

比較結果を得るもの。
compareToみたいなもの。


これらがそれぞれequal, less than, greater thanを表しています。

これが素晴らしいところはOrderingがモノイドであること。

これにより、優先順位の高い比較結果から順に結合していくことで適切な比較結果を得られます。


比較結果モノイドについては、 比較はモノイド の記事が面白いので是非見て下さい。

lt, gt, lte, gte

比較する関数です。
標準のものと違うところは型安全なところと、記号じゃないから括弧で括らないといけないところ。


max, min

2値の間で最大、最小を得る関数。


Orders

order, orderBy

Orderのインスタンスを作ります。
orderは2つの値を取り比較結果を返す関数を渡します。
orderByは値を取り、比較可能な値を返す関数を渡します。


scala標準のOrderingも暗黙の型変換でOrderのインスタンスを得ることができます。

比較する際はjava.lang.Comparable, scala.math.Orderingよりもscalaz.Orderの検討を!

2011年12月3日土曜日

Show

今日はShowについて。

Showは表示可能という性質を与えます。

インスタンスは普通にnewで作ることもできますが、Showsに定義された関数を使っていきましょう。

Shows


showは値を受け取り、List[Char]を返す関数を渡します。
文字列ではなく、List[Char]なのはHaskellをリスペクトしてるからでしょうか?
文字列に対してはtoListなどを呼ばないといけません。

それに対してshowsはStringを返す関数を渡せばいいので、こちらを使うことが多いと思います。

showAはShowをtoStringにより実装します。
case classなどはこれでいいかもしれません。

showByは値を取り、Showのインスタンスを持つ型を返す関数を渡します。

基本的にはshowAとshowsを使っていきましょう。

Showを使う関数

show
shows

Showで定義した文字列を取得する関数。
toStringとは違い、表示できることが保証されています(大抵の場合、"A@17d577c"などの文字列は返らない)。


print
println

名前通りの関数。
rpscalaで初めて気がついた。


text

scala.xml.Textを返す関数・・・・・需要あるの?
scala.xml.Elemのインスタンスはデフォルトでは存在しない模様。
こっちの方が重大じゃなイカ。


これらの関数と昨日紹介したassert_===など。
他にもLoggerやWriterに関係するものがあったりするけどまた今度。

2011年12月2日金曜日

Equal

Equalは型クラスです。
型クラスについては10日にやるScala会議で話す資料とか水島さんの死霊とか。

この型クラスは等しいという性質を与えます。

作り方


最初の方法はEqualのインスタンスを直接作るというもの。
二番目の方法はequalを使う方法。
equalは2つの値を受け取り、Booleanを返す述語を渡す。
三番目のequalAはequalをAnyの==を使って実装するというもの。
equalAとequalはEqualsに定義されており、Scalazがそれを継承しています。
この3つはどれも同じEqual[ScalaChan]が作られます。

Eqaulを利用した関数

===
/==

見た目通り等しい、等しくないを返す関数。
標準の==,!=と違うところは型安全というところ。


糖衣関数?もある。


Equalだけを利用した関数が少なすぎて物悲しいのでもう一個

assert_===

Unit TestライブラリによくあるassertEqual的なもの。
エラーメッセージがちょっとかっこいい。
この関数は値がEqualの他にShowのインスタンスを持つことが必要です。


基本的なEqualのインスタンスはEqualのコンパニオンオブジェクトに定義されています。
自分で定義したclassはequalやequalAでインスタンスを作っておきましょう。

Identity

一人Scalaz Advent Calendar

初日ということでIdentityから。

Identityの説明だけれど型クラスに関連するもの(===とか|+|とかほとんどの関数)やScalazのデータ構造(Validation,LazyTupleなど)に関するものは取り扱わないです。
後日EqualやSemigroup,Validationなどを説明するときに出てきます。

Identityは型パラメータAをとり、def value: Aという未定義の関数を持ちます。
パラメータAに様々な関数を提供するコンテナと考えてよいでしょう。


Identitys

IdentitysのmkIdentityによって全ての値はIdentityに暗黙の型変換することができます。
また、unMkIdentityによりIdentityをもとの値に戻すことも可能です。


unitalという謎のIdentity[Unit]が定義されているけど何に利用するかは不明。


Identity

??


簡単に言うとnullチェック。
nullだった場合は引数で与えた値が返る。


|>

関数に呼び出し側の値を適用する関数。
ちょっと意味がわからない、コードを見ましょう。


some, left, right, pair, squared

ある型に包む関数。
pairとsquaredは値のペアをタプルで返す。
def squared = pairみたいな定義だけどいるんですかこれ。


doWhile, whileDo

名前通りの関数。
関数と述語を渡す。


Scalazの型クラス、データ構造に関するものを抜くとこれだけ。

これだけではScalazの便利さがわからないと思うので、ぜひ続きも見て下さい!