LoginSignup
3
5

More than 5 years have passed since last update.

Functorについてメモ

Last updated at Posted at 2015-11-11

概要

Functorとは構造内の値に関数を適用できるもので、
Functor: (a -> b) -> f a -> f b
である。とはどういうことか。

圏論について

圏論とは、数学的な構造を持った「対象」と、対象間の「射」からなる。
関数 fInt を引数に取り String を返すとすると、 f: Int -> String と表記できる。この場合、Int, String など(一般的に型と呼ばれるもの)は「対象」であり、 f は「射」である。

a -> b -> c とは

HaskellやLISP, OCaml などの関数型言語を考える。関数型は、関数が第一級であり、関数が射であると同時に対象でもある。また、Haskellなどにおいて、関数は、引数(対象)をひとつ取り、返り値を1つ返す。

では、引数を2つ以上取りたい場合はどうするか。具体的には、 f(x, y) = x + y なる関数を定義したいという欲求が出てくる。ここで登場するのが f: a -> b -> c (関数のカリー化)である。

分かりやすいように、f: Int -> Int -> Int とする。これは、f: Int -> (Int -> Int) という意味である。 fInt を渡すと、 g: Int -> Int という関数が返ってくる。これに対してさらに Int を渡すと、 Int が返ってくる。

f(x: Int) = g(y: Int) = x + y
g = f(2) // = g(y: Int) = 2 + y
g(3) // = 5

f2 を渡すと、yを受け取って+2をする関数 が返ってくるので、そいつに更に 3 を渡します。これで足し算を実現しています。つまり、

f(2)(3) // = 5

構造体とは

Scalaの List[String] とかを考える。(Scalaは純粋関数型ではなく、クラスが関数 - 正確にはメソッド - を持つので特殊だが)

list = List("first", "second", "third")
list(0) // => "first"

Scalaにおいて、 list(0)list.apply(0) のことである。
list.applyInt -> String となる。
この apply のような、構造体から値を取り出すような操作を extract と言う。

Map[String, String] の extract は String -> String である。

Functor とは

Functorとは構造内の値に関数を適用できるもので、Functor: (a -> b) -> f a -> f b である。

FunctorはScalaでいう map である。Scalaのmapの実装を見てみると

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

いかにも Functor っぽい感じになっている。

(a -> b) -> f a -> f b とは (a -> b) -> (f a -> f b) となる。ここにおける、 f というのが List であり、Functorは、関数 a -> b を受け取り、構造体の中身に a -> b を適用し、構造体を返す。

次は Applicative

参考

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5