2015-06-06 9 views
6

W Scali, jeśli utworzysz typeclass, powiedzmy, struktura algebraiczna Monoid[T], możesz podać wiele domyślnych implementacji typeclass dla różnych typów, które są monoidami.Jak zapewnić domyślną typeclass dla typów ogólnych w Scali?

Załóżmy, monoid jest zdefiniowany jako:

trait Monoid[T] { 
    def op(x: T, y: T): T 
    def id: T 
} 

Since String S w formie pracy konkatenacji monoid, można zapewnić domyślny monoid do String jest jak poniżej:

implicit object StringMonoid extends Monoid[String] { 
    override def op(a: String, b: String): String = a + b 
    override def id: String = "" 
} 

to raczej łatwe, ponieważ String nie jest typem ogólnym.

To, o co pytam, to: , jak zapewnić domyślny monoid dla Seq[T] s, w którym parametr type uniemożliwia mi utworzenie niejawnego obiektu, jak to zrobiłem powyżej.

mogłem zrobić:

class SeqMonoid[T] extends Monoid[Seq[T]] { 
    override def op(a: Seq[T], b: Seq[T]): Seq[T] = a ++ b 
    override def id: Seq[T] = Nil 
} 
implicit object intSeqMonoid extends SeqMonoid[Int] 
implicit object doubleSeqMonoid extends SeqMonoid[Double] 
implicit object stringSeqMonoid extends SeqMonoid[String] 
... 

Ale takie podejście nie wykorzystuje piękno typów generycznych.

Na ogół moje pytanie brzmi: czy jest jakiś sposób w Scali, mogę zapewnić implementacje typeclass dla typów ogólnych?

Odpowiedz

7

Możesz podać niejawny funkcji z wymaganego typu:

implicit def SeqMonoid[T]: Monoid[Seq[T]] = new Monoid[Seq[T]] { 
    override def op(a: Seq[T], b: Seq[T]): Seq[T] = a ++ b 
    override def id: Seq[T] = Nil 
} 
+1

jeśli istnieje sposób, aby nie powtarzać 'Seq [T]' w tak wielu miejscach ? –

+1

Czy nie utworzy to nowego obiektu za każdym razem, gdy potrzebne jest 'Monocyt [Seq [T]]'? –

+0

@YuhuanJiang Tak, ale tak naprawdę nie masz wyboru, jeśli chcesz, aby był ogólny. –

0

Variation bez powtarzania Seq[T]:

object Monoid { 
    implicit def seqMonoid[T]:Monoid[Seq[T]] = { 
    type S = Seq[T] 
    new Monoid[S] { 
    def op(x: S, y: S) = x ++ y 
    def id = Nil 
    } 
    } 
} 
+2

Uznałbym to za mniej idiotyczne i trudniejsze do odczytania. –

Powiązane problemy