Scala/confused

Scala のコードを読んでいて, 読み方 (脳内 parse) や意味が分からなかったところをメモしていきます. 他の人が書いた Scala のソースコードが読めなくて困ってる人に役立って欲しいのもありますし, Scala をよく知らない人が躓きやすいところを上級者に知ってもらえればと思っています.

implicit parameter

「その環境にあるやつを使う」とか「呼び出し引数が 1 つ足りない (ように見える)」とかが不思議でした. 定義を見れば分かるので, まだ混乱度合いとしてはマシな方です.

final override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That = {
  if (bf eq List.ReusableCBF) {
    if (this eq Nil) Nil.asInstanceOf[That] else {
      val h = new ::[B](f(head), Nil)
      var t: ::[B] = h
      var rest = tail
      while (rest ne Nil) {
        val nx = new ::(f(rest.head), Nil)
        t.tl = nx
        t = nx
        rest = rest.tail
      }
      h.asInstanceOf[That]
    }
  }
  else super.map(f)
}

(https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/immutable/List.scala#L270-L286 より引用)

self type

ここに出てくる => を見て「関数? でもなんでこの位置で??」と混乱してしまいました.

Java で言う this と同じ働きをするらしいです. いわゆる late binding な, 自身を指す変数です.

abstract class Enumeration (initial: Int) extends Serializable {
  thisenum =>

(https://github.com/scala/scala/blob/v2.11.7/src/library/scala/Enumeration.scala#L54-L56 より引用)

HogeOps class

Scalaz で良く見掛けるやつです. 正直これの役割はさっぱり分からなかったです. Ops って接尾語が付くので「演算子 (Operator) に関係がある??」と混乱してました.

まだ良く分かってないけど,「型クラスを使ったコードを便利に書くためのもの」くらいの理解でいます.

/** Wraps a value `self` and provides methods related to `Functor` */
final class FunctorOps[F[_],A] private[syntax](val self: F[A])(implicit val F: Functor[F]) extends Ops[F[A]] {
  ////
  import Leibniz.===

  final def map[B](f: A => B): F[B] = F.map(self)(f)
  final def distribute[G[_], B](f: A => G[B])(implicit D: Distributive[G]): G[F[B]] = D.distribute(self)(f)
  final def cosequence[G[_], B](implicit ev: A === G[B], D: Distributive[G]): G[F[B]] = D.distribute(self)(ev(_))
  final def cotraverse[G[_], B, C](f: F[B] => C)(implicit ev: A === G[B], D: Distributive[G]): G[C] = D.map(cosequence)(f)
  final def ∘[B](f: A => B): F[B] = F.map(self)(f)
  final def strengthL[B](b: B): F[(B, A)] = F.strengthL(b, self)
  final def strengthR[B](b: B): F[(A, B)] = F.strengthR(self, b)
  final def fpair: F[(A, A)] = F.fpair(self)
  final def fproduct[B](f: A => B): F[(A, B)] = F.fproduct(self)(f)
  final def void: F[Unit] = F.void(self)
  final def fpoint[G[_]: Applicative]: F[G[A]] = F.map(self)(a => Applicative[G].point(a))
  final def >|[B](b: => B): F[B] = F.map(self)(_ => b)
  final def as[B](b: => B): F[B] = F.map(self)(_ => b)
  ////
}

(https://github.com/scalaz/scalaz/blob/v7.1.4/core/src/main/scala/scalaz/syntax/FunctorSyntax.scala#L4-L23 より引用)