2016-06-20 10 views
1

暗黙のエビデンスオブジェクトを参照しなくても、型クラスの関数を直接使用したいと考えています。暗黙のエビデンスオブジェクトなしで直接Scala型のメガネを使用する

今、私は型クラスに推奨される方法(少なくとも私はそう思う)に実装している:私が書きたいのですが

def addTwice[A](x: A, y: A)(implicit ev: Monoid[A]): A = { 
     ev.append(ev.append(x,y), y) 
} 

object Main { 
    import Implicits._ 
    import Implicits.monoidInt._ 

    def main(args: Array[String]): Unit = { 
     println(addTwice(1,2)) 
    } 
} 

object Implicits { 
    implicit object monoidInt extends Monoid[Int] { 
     def zero: Int = 0 
     def append(x: Int, y: Int): Int = x + y 
    } 
} 

trait Monoid[A] { 
    def zero: A 
    def append(x: A, y: A): A 
} 

代わりのようaddTwiceを書くことを

def addTwice[A: Monoid[A]](x: A, y: A): A = x.append(y).append(y) 

これは可能ですか?

+0

'A:Monoid'の間は'暗黙的に[Monoid [A]] 'ですか? – cchantep

+0

申し訳ありませんが、私はその質問を理解できません。 – TomTom

+0

「暗黙的に」十分ですか? – cchantep

答えて

6

はい可能です。いわゆるOpsが必要です。定義された型クラスのインスタンスを持つクラスのオブジェクトにメソッドを追加することができます。

typeclassの値とインスタンスを持つ特性のMonoidOpsを定義し、そのメソッドでその特性を使用するので、基本的にはその変数evの使用をカプセル化します。

AからMonoidOps[A]への変換を定義します。暗黙的なパラメータを使用してオブジェクトとインスタンスを設定します。

trait Monoid[A] { 
    def zero: A 
    def append(x: A, y: A): A 
} 

object Implicits { 
    implicit object monoidInt extends Monoid[Int] { 
     def zero: Int = 0 
     def append(x: Int, y: Int): Int = x + y 
    } 

    trait MonoidOps[A] { 
     def instance: Monoid[A] 
     def self: A 
     def |+|(y: A): A = instance.append(self, y) 
    } 

    implicit def toMonoidOps[A](target: A)(implicit M: Monoid[A]) = new MonoidOps[A] { 
     val instance = M 
     val self = target 
    } 
} 

import Implicits._ 

def addTwice[A: Monoid](x: A, y: A): A = x |+| y |+| y 

scala> println(addTwice(1,2)) 
5 

MonoidOpstoMonoidOpsは次のように暗黙のクラスに置き換えることができます:

implicit class MonoidOps[A](val self: A)(implicit M: Monoid[A]) { 
    def |+|(y: A): A = M.append(self, y) 
} 

はあなたのための定型文を生成することができsimulacrumプロジェクトを見てみましょう。

+0

私はScalaを新しくしましたが、simulacrum型のtypeclass作成が言語自体に組み込まれていない理由はありますか? – TomTom

+0

これは他のすべてのライブラリが言語に統合されていないのと同じ理由だと思います。それらは単なるライブラリです。使用したい場合は、ファイルをビルドするために追加し、使用しない場合は使用します。 –

+0

私は参照してください...私はtypeclassesが合意された構文的な砂糖の恩恵を受ける言語の中心的な機能だと思います。 – TomTom

関連する問題