Scala における method と 関数(function) の違いとは？ - 関数合成

# <i class="fa fa-anchor" style="font-size:1em;"></i> なんでこんなことを思ったか
ちょっとHaskellをみていて、関数合成ということばが出てきて、そういえばScalaにも関数合成(composeとかandThen)あったよなぁと思い出した。
それで、いざ使ってみようと思ったら「関数とは？」とふと思ってしまった。

以下、あんまりまとまってないので、そのうち書きなおすかも。

# <i class="fa fa-comment" style="font-size:1em;"></i> ネット上の意見

## <i class="fa fa-comments" style="font-size:1em;"></i> その1
[What is the difference between a method and a function](http://stackoverflow.com/questions/155609/what-is-the-difference-between-a-method-and-a-function)

Objectに関連するものがメソッド、そうでなく独立しているものが関数である。
ふむ？

## <i class="fa fa-comments" style="font-size:1em;"></i> その2
[Scala def versus val](http://stackoverflow.com/questions/3646756/scala-def-versus-val)
valがfunction、defがmethodである?
ふむむ？

## <i class="fa fa-comments" style="font-size:1em;"></i> その3
[関数にしか見えないものが「メソッド」と新たな名前で呼ばれる理由(1)](http://d.hatena.ne.jp/amapetas/20111114/1321237707)

override可能なものがmethodで、不可能なものがfunction
ということはdefがmethodで、valがfunction？
以下の通りであるということか？

### <i class="fa fa-question" style="font-size:1em;"></i> メソッド(def)
override 可能

```scala
/**
 * 文字列をInt型の逆リストに変換
 * */
private def toReverseIntList(s: String): List[Int] = {
    s.sliding(1).map(_.toInt).toList.reverse
}

```

### <i class="fa fa-question" style="font-size:1em;"></i> 関数(val)
override 不可能

```scala
private val toReverseIntList = (s: String) => {
    s.sliding(1).map(_.toInt).toList.reverse
}
```

# <i class="fa fa-mortar-board" style="font-size:1em;"></i> 考える
その1が曖昧。
Objectに関連するものはdefでもvalでもメソッドになるというのか？

# <i class="fa fa-key" style="font-size:1em;"></i> おそらく答え
※英語は読むのに根気がいるのでまだ読めていない
[Difference between method and function in Scala](
http://stackoverflow.com/questions/2529184/difference-between-method-and-function-in-scala)

# <i class="fa fa-spinner" style="font-size:1em;"></i> methodを定義すべきか、functionを定義すべきか
はてさて・・・

defでも、valでも関数合成は可能なんだなぁ

# <i class="fa fa-puzzle-piece" style="font-size:1em;"></i> 関数合成

## <i class="fa fa-terminal" style="font-size:1em;"></i> def バージョン
```scala
/**
 * Created by FScoward on 15/01/18.
 */
object Luhn {
 
  /**
   * Luhn algorithm
   * */
  def isValid(s: String): Boolean = {
    // val list = doubleOddValues(toReverseIntList(s))
    // sum(list) % 10 == 0
    // ↑はいつもの使い方
    (sum _ compose doubleOddValues _ compose toReverseIntList _)(s) % 10 == 0
  }
 
  /**
   * 偶数桁の値を倍にして返す
   * */
  private def doubleOddValues(list: List[Int]): List[Int] = {
    (0 until list.size).map(i => {
      if (i % 2 == 0) {
        list(i)
      } else {
        list(i) * 2
      }
    }).toList
  }
 
  /**
   * 文字列をInt型の逆リストに変換
   * */
  private def toReverseIntList(s: String): List[Int] = {
    s.sliding(1).map(_.toInt).toList.reverse
  }
 
  /**
   * リストの値を合計する
   * 但し、2桁以上の数字は分割して加算する
   * */
  private def sum(list: List[Int]) = {
    list.map(i => {
      i match {
        case i if i > 9 => {
          i.toString.sliding(1).map(_.toInt).sum
        }
        case i => {
          i
        }
      }
    }).toList.sum
  }
}
 
```

## <i class="fa fa-terminal" style="font-size:1em;"></i> val バージョン
```scala
object Luhn {

  /**
   * Luhn algorithm
   * */
  def isValid(s: String): Boolean = {
    (sum compose doubleOddValues compose toReverseIntList)(s) % 10 == 0
  }

  /**
   * 偶数桁の値を倍にして返す
   * */
  private val doubleOddValues = (list: List[Int]) => {
    (0 until list.size).map(i => {
      if (i % 2 == 0) {
        list(i)
      } else {
        list(i) * 2
      }
    }).toList
  }

  /**
   * 文字列をInt型の逆リストに変換
   * */
  private val toReverseIntList = (s: String) => {
    s.sliding(1).map(_.toInt).toList.reverse
  }

  /**
   * リストの値を合計する
   * 但し、2桁以上の数字は分割して加算する
   * */
  private val sum = (list: List[Int]) => {
    list.map(i => {
      i match {
        case i if i > 9 => {
          i.toString.sliding(1).map(_.toInt).sum
        }
        case i => {
          i
        }
      }
    }).toList.sum
  }
}
```

なお、sumだけ`val sum = (list: List[Int]) =>`の形で書けばあとはdefで書いても関数合成できる。

# <i class="fa fa-exchange" style="font-size:1em;"></i> 違い
def バージョン だと`_`で関数オブジェクト化する必要がある。

# <i class="fa fa-child" style="font-size:1em;"></i> つまり
def は関数ではない？

# <i class="fa fa-question-circle" style="font-size:1em;"></i> よくわからない
言語に詳しい諸兄方のご意見ください。