Skip to content

Instantly share code, notes, and snippets.

@gakuzzzz
Last active October 3, 2015 10:35
Show Gist options
  • Save gakuzzzz/f341db10bcf9af78ae87 to your computer and use it in GitHub Desktop.
Save gakuzzzz/f341db10bcf9af78ae87 to your computer and use it in GitHub Desktop.
interface MyFunctor<A> {
    fun myMap<B>(f: (A) -> B): MyFunctor<B>
}
class MyFunctorList<A>(val list: List<A>) : MyFunctor<A>, List<A> by list {
    override fun myMap<B>(f: (A) -> B): MyFunctor<B>
        = MyFunctorList(list.map(f))

    override fun toString() = list.toString()
}

fun <A> List<A>.asFunctor(): MyFunctorList<A>
    = MyFunctorList(this)
fun main(args: Array<String>) {
    println(arrayListOf(1, 2, 3, 4, 5).asFunctor().myMap { n -> n * 3 })
}

もし上記と同じ内容を Scala で示すなら以下のようになります。

trait MyFunctor[A] {
  def myMap[B](f: A => B): MyFunctor[B]
}
class MyFunctorList[A](list: List[A]) extends MyFunctor[A] {
  def myMap[B](f: A => B): MyFunctor[B]
    = MyFunctorList(list.map(f))

  override def toString = list.toString
}

implicit class ListOps[A](list: List[A]) {
  def asFunctor: MyFunctorList[A] = new MyFunctorList(list)
}
def main(args: Array[String]) {
    println(List(1, 2, 3, 4, 5).asFunctor.myMap { _ * 3 })
}

ただ、これでは myMap が返す値が MyFunctor[B] のため、List[B] を取り出したりすることができません。

またスライドで最初にあげたScalaコードとは意味合いが異なります。

資料の中で「implicitだらけでScala怖い」と表現した件については、今でも可読性に難のある機能だと感じています。

とありますが、同等のコードでは implicit 1個しか出てきません。

もちろん implicit を使って可読性に難のあるコードを書くことは出来ますが、上記比較をもって「implicitだらけで可読性に難のある」と主張するには暴論のように思えます。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment