2015-06-06 35 views
6

Trong Scala, nếu bạn tạo một typeclass, nói cấu trúc đại số Monoid[T], bạn có thể cung cấp nhiều triển khai kiểu chữ mặc định cho các loại khác nhau là monoids.Làm thế nào để cung cấp một typeclass mặc định cho các loại chung trong Scala?

Giả sử một monoid được định nghĩa là:

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

Kể từ String s dưới hình thức hoạt động nối một monoid, chúng tôi có thể cung cấp một monoid mặc định cho String s như thế này:

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

Đây là khá dễ dàng, vì String không phải là loại chung.

Điều tôi đang yêu cầu là cách cung cấp monoid mặc định cho Seq[T] s, trong đó thông số loại ngăn tôi tạo đối tượng ẩn như tôi đã làm ở trên.

tôi có thể làm:

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] 
... 

Nhưng phương pháp này không sử dụng vẻ đẹp của các kiểu generic.

Vì vậy, nói chung, câu hỏi của tôi là: Có cách nào trong Scala tôi có thể cung cấp triển khai typeclass cho các loại chung không?

Trả lời

7

Bạn có thể cung cấp một chức năng tiềm ẩn với các loại yêu cầu:

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

nếu có một cách để không lặp lại 'Seq [T] 'trong rất nhiều nơi ? –

+1

Điều này sẽ không tạo ra một đối tượng mới mỗi lần một 'Monoid [Seq [T]]' là cần thiết? –

+0

@YuhuanJiang Có, nhưng bạn không thực sự có lựa chọn nếu bạn muốn nó là chung chung. –

0

Biến thể mà không lặp lại 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

Tôi cho rằng điều này ít thành ngữ và khó đọc hơn. –

Các vấn đề liên quan