Scala: How can I create a function that allows me to use dot notation when calling it?

≡放荡痞女 提交于 2019-12-04 14:53:49

For the first part of your question, you probably need to look at implicit classes:

  implicit class RichRVLList[A](l:List[A]) {
    def foldRVL[B](z: B)(f: (A, B) => B) = //"Right-Via-Left"
      l.reverse.foldLeft(z)((a, b) => f(b, a))
  }

  List(1,2,3).foldRVL(1)(_ + _)  // output: res0: Int = 7

You can "enrich" existent class using implicit wrapper to "add" new methods.

As for the second part, probably you want implicit parameters. Implicit parameters are deduced from the current scope by type. There are some predefined implicit values, such as Numerics, that were used in the example below:

  def product[T](els:TraversableOnce[T])(implicit num:Numeric[T]) = {
    els.fold(num.one)((x1, x2) => num.times(x1, x2))
  }      

  product(List(1, 2, 3)) // res1: Int = 6
  product(List(1, 2.5, 3)) //res2: Double = 7.5

soong pointed out that I'm actually seeking the 'Pimp my library' pattern, which I then looked up, and implemented like this to handle the method in question:

implicit class BlingList[+A](l: List[A]) {
  def foldRVL[B](z: B)(f: (A, B) => B): B = //"Right-Via-Left"
    l.foldLeft(z)((a, b) => f(b, a))
}

As far as I understand, the key element to allowing dot-notation is having a class construct that takes parameters of the type that I want to have 'pimped'. In this case, I have a list, and I want to call foldRVL on the list after I write the list down, like this: List(something).foldRVL(z)(f: A => B). Therefore, I need a class that takes a List[A] parameter for me to be able to write a method like that in the first code snippet.

The implicit keyword is used so that I can add methods to the existing class List without having to create a separate Library of methods. Anytime a List is found prefixed before foldRVL, it will be implicitly converted into a BlingList because the compiler will see a List attached to a method that doesn't exist in class List. It will therefore look for any implicit methods defined in scope that have a foldRVL method and take a List as an argument, and it finds that the implicit class BlingList has the method foldRVL defined and takes a List[A]. Therefore, I can now write:

List(1,2,3).foldRVL(0)(_ + _) // in some IDE's, foldRVL will be underlined to show that
res0: Int = 6                 // an implicit conversion is being made

"A Scala 2.10 implicit class example" goes into more depth about this. My favorite pointer from that post is to put all the implicit classes that you expect to be using in your current package and any subpackages inside of a package object, that way you don't have to clutter any of your classes or objects with implicit class definitions, nor do you have to import them. The fact that they are using the same package will automatically import them thanks to the package object.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!