言うまでもなく、Requestからデータを取り出す部分が無駄に長い。
これは、urlFormEncodedのbodyの型がMap[String, Seq[String]]だから。もちろんプロトコル上はこの型が妥当なのだが、大抵の場合はValueは1つだけ値があれば十分なので、Seqから1個取り出すのが冗長に感じられるわけだ。
じゃあ、ということで、以下の様な関数を作ってやればとりあえず短くはなる。
短くはなるんだけど、ただ単純に処理を切り出しただけ。使ってみるとわかるけど、あんまりScalaっぽくない。
せっかくScala使ってるんだから、型クラス使いたいよね!
というわけで、こうなった。
paramOpt関数がControllerから呼び出す関数。
こいつはimplicit parameterでExtractor[T]を受け取っていて、そのExtractorのextract関数を利用してデータ抽出を行う。
paramOpt関数自信も型パラメータを持っていて、そこに指定された型に合ったExtractorが選択されて使われるわけだ。
extractorByみたいな関数も用意しておけば、IntExtractorの様に、既存のExtractorと型変換用関数を組み合わせて新たなExtractorを構成するのも簡単だ。
Extractor[T]を使って最初のPersonの例を書きなおすとこうなる。
スッキリ!
追記:
extractorByの中身、何をやってるかって言うと、A => Option[B] と B => Option[C] を組み合わせて A => Option[C] を作ってるんだよね。で、
A => Option[B] と B => Option[C] を組み合わせて A => Option[C] を作るのって、scalaz的にはどうやるのが一番カッコイイですか・・・?
— Hirokazu NISHIOKAさん (@nisshieeorg) 7月 16, 2012
って呟いたら、反応されてた。
(無駄に?) kleisli 使って☆(f) >=> ☆(g) apply _とか?( scalaz6 )twitter.com/nisshieeorg/st…twitter.com/nisshieeorg/st…
— Kenji Yoshidaさん (@xuwei_k) 7月 16, 2012
やっべ、kleisliわかんねぇ。勉強します。。。
0 件のコメント:
コメントを投稿