Haskell と Scala

start haskell 2 第5回 クリエイティブ・コモンズ・ライセンス

自己紹介

  • Scalaは詳しいけど、Haskellはあまり詳しくありません(>_<)
  • なので、HaskellよりScalaの話が多いです(ぇ
  • Scalaをdisりに来ました(ぇ

すいません、宣伝

Scala Conference in Japan というのをやります!


  • 海外から、Scala作ってる中の人やAkkaという有名なライブラリを作ってる人が来ます!
  • http://scalaconf.jp/
  • 2013年3月2日(土)
  • 東京工業大学(大岡山キャンパス)
  • Haskell 使ってる人から見て、Scalaのイメージとは?
  • そもそもScala使ったことあるのか?
  • Scalaについてどれくらい知ってるのか?
  • Scalaは関数型言語なのか?

Haskellと比べてScalaのだめなところ 1

  • 型推論弱い (一応overloadの関係などある程度理由はあるらしい)
  • Option を使うことにより減りますが null からは完全に逃れられない・・・
  • 標準で、 Monad とか Applicative とかがない・・・?
  • 型クラス・・・?
  • Haskellよりコンパイル遅い
  • デフォルト遅延評価ではない (これは、メリットもあるけど)

Haskellと比べてScalaのだめなところ 2

今日とりあえず一番言いたいこと

Scalaでの型クラスについて!
  • Scalaには型クラス専用の構文はない(?)
  • けど、型クラスはそれなりに使われている
_人人人人人人_
> implicit <
 ̄^Y^Y^Y^Y^ ̄
  • implicit という謎の予約語がある
  • 暗黙・・・?
  • なにそれこわい
  • Scalaが複雑とか言われてしまう原因の一つ・・・?
implicit は、型クラスのための構文です(キリッ
  • implicit conversionimplicit parameter という2種類がある
  • implicit conversion は型クラスには、ほとんど関係ないので忘れてください

型クラスの定義



trait Functor[F[_]]{
  def fmap[A, B](r: F[A], f: A => B): F[B]
}


https://github.com/scalaz/scalaz/blob/v6.0.4/core/src/main/scala/scalaz/Functor.scala#L14

class  Functor f  where
    fmap        :: (a -> b) -> f a -> f b

https://github.com/ghc/packages-base/blob/ghc-7.4.2-release/GHC/Base.lhs#L179

型クラスのインスタンスの定義



implicit def OptionFunctor: Functor[Option] =
  new Functor[Option] {
    def fmap[A, B](r: Option[A], f: A => B) = r map f
  }

https://github.com/scalaz/scalaz/blob/v6.0.4/core/src/main/scala/scalaz/Functor.scala#L112

instance  Functor Maybe  where
    fmap _ Nothing       = Nothing
    fmap f (Just a)      = Just (f a)

https://github.com/ghc/packages-base/blob/ghc-7.4.2-release/Data/Maybe.hs#L72

とりあえず、Scalaで以下のものがでてきたらほとんどの場合型クラスのインスタンス定義だと思えばいい


  • implicit val
  • implicit object
  • (実引数なしで、型引数のみの) implicit def

重要なこと1

implicit parameterによる型クラスは 「偶然エミュレートできた」のではなく、 最初から型クラスをエミュレートすることを意図して入れた! という事実


詳しく知りたい人は、Scalaの作者自らが書いた、この論文とか読んでください

Type Classes as Objects and Implicits

重要なこと2

Scalaには、for式というものがありますが、ループのための構文ではなく Monadのための構文 です!

  • 詳しいことは今日は解説しないけど、Haskellのdoと目的はだいたい同じ
  • for式の一部の機能だけ使うと、なんとなくループっぽいから初級者〜中級者向けの解説では、それを説明してない
  • さらに詳しいことを言えば、パターンマッチでfilterできたり、ifガードがあるので、MonadPlus相当(?)

ところで、さっきのFunctorの定義は、Scala標準ライブラリにはありません

_人人人人人_
> Scalaz <
 ̄^Y^Y^Y^Y ̄

Scalaz とは・・・?

  • Scala標準ライブラリにほとんど型クラスの定義がない
  • 大量の型クラスの定義
  • Scalaで型クラスを使ったプログラミングをするなら必須
  • ほかにも似たようなライブラリあるけど、あまり使われてない okomok/ken
  • なのでデファクトスタンダード
  • Edward A. Kmett さんが、4番目に多くコミットしてる!?
  • Haskell界隈で有名な人
  • comonad.com の人
  • Lens とかHaskellの有名なライブラリいっぱい作ってる

でも、Scalaをdisってたよ(>_<)

Scala

implicit def KleisliCategory[M[_]: Monad]: Category[({type λ[α, β]=Kleisli[M, α, β]})#λ]
  = new Category[({type λ[α, β]=Kleisli[M, α, β]})#λ] {
    def id[A] = ☆(_ η)
    def compose[X, Y, Z](f: Kleisli[M, Y, Z], g: Kleisli[M, X, Y]) = f <=< g
  }


Haskell

instance Monad m => Category (Kleisli m) where
  id = Kleisli return
  Kleisli f . Kleisli g = Kleisli (f <=< g)

Scalazにある型クラスの例

Equal(HaskellのEq)、Show、Order(HaskellのOrd)、Functor、Applicative、Monad、MonadPlus、Monoid、Arrow、Zipper、State、Writer、Reader、Traverse、IO、Kleisli、Free、Comonad、Bifunctor、Category、Cojoin、CoKleisli、Each、Endo、Cofree、Group、Length、Lens、Partial Lens、Semigroup、Zip、Zipper、Zap

ちょっと話逸れます

一週間くらい前

Stackless Scala With Free Monads

Free Monadが流行る

200RT以上!?

tanakh free

  • Haskellでも、まだあまり使われてないもの( Free Monad や Partial Lens など )まで、Scalaでできるらしい
  • でもとにかく型をいっぱい書かなければいけなくて大変!
  • Scalaで型クラスを使ったプログラミングをする利点とは・・・?

1点だけ利点があるらしい

Haskellと違いScalaでは 型クラスのインスタンスを複数持てる(スコープによって自分で制御できる)
  • それは嬉しいのか・・・?
  • 型クラスのインスタンスを複数持ちたいことってあまりない・・・?
  • newtypeあるし
  • Haskellそれほど書いたことないから、そのあたりの感覚がよくわからない
  • 将来的にGHCでも、そのあたりの制限を緩和するという話を聞いたことが(?) (もしくは既に最新版に入ってる?)
  • 詳しくないのでだれか教えてください(>_<)
  • 最終的に (Haskellerが) Scalaをやるメリットとは・・・?
  • Haskellと比べてScalaをやったほうがいい人とは?
  • たぶんHaskellが既にそれなりにできるなら、それほどScalaメリットない(?)
  • 逆にScalaだけやってるひとがHaskellやるのはある程度メリットある気がする
  • 仕事に関数型言語導入したくて、「Haskellの導入は難しそうだけど、Scalaなら導入できるのではないか?」という人はScalaやっておくといいかも・・・?
  • 平凡な結論だが「Javaを知っていて、関数型プログラミングやりたい」という人にとっては、HaskellよりもScalaのほうが、「手続き型から徐々に関数型なプログラミングに移行しやすい」という点では入門しやすいかもしれない
  • けど、本格的に型クラスを大量に使うスタイルでプログラミングをやろうとすると、ほとんどの場合Haskellのほうが簡潔に書ける
  • ただ、(冗長だけれども) Haskellで現状あるほとんどの型クラスは、Scalaでもすでに存在していて型クラスを使ったプログラミングができる!という事実がそこまで知られていないので、もうちょっとその事実が広まってもいいと思う

おわり。ありがとうございました