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?
jeśli istnieje sposób, aby nie powtarzać 'Seq [T]' w tak wielu miejscach ? –
Czy nie utworzy to nowego obiektu za każdym razem, gdy potrzebne jest 'Monocyt [Seq [T]]'? –
@YuhuanJiang Tak, ale tak naprawdę nie masz wyboru, jeśli chcesz, aby był ogólny. –