2013-03-25 3 views
22

나는 scalaz 상당히 새로운 그리고 난 다음 코드가 작동하는 이유를 알아 내려고 노력하고 있어요 :왜 목록은 세미 그룹이지만 Seq는 아닌가?

import scalaz._ 
import Scalaz._ 
scala> Map[String,List[String]]() |+| Map[String,List[String]]() 
res3: scala.collection.immutable.Map[String,List[String]] = Map() 

을하지만이 ...하지 않는

import scalaz._ 
import Scalaz._ 
scala> Map[String,Seq[String]]() |+| Map[String,Seq[String]]() 
<console>:14: error: value |+| is not a member of  scala.collection.immutable.Map[String,Seq[String]] 
      Map[String,Seq[String]]() |+| Map[String,Seq[String]]() 

내가 대한지도 암시 적 참조 Semigroup,하지만 List 또는 Seq에 대해서는 표시되지 않습니다.

커플 질문 :

ListSemigroup에 대한 암시 적
  1. ?
  2. Seq 용으로 왜없는가요?
+0

어떤 버전을 사용하고 있습니까? Semigroup.scala에 대한 링크가 6.x 인 master로 연결되는 동안 태그에 따르면 scalaz-seven에 대해 묻습니다. – folone

+0

7 번을 사용하고 있습니다. 링크를 수정하겠습니다. – coltfred

답변

27

따라서 Scalaz 7에는 Monoid[List[A]]을 다시 제공하는 implicit List to Monoid function이 있습니다. MonoidSemiGroup으로 확장되므로 목록을 작성했습니다.

Seq이 특별한 대우를받지 못합니다. Seq에서 Monoid 또는 Semigroup으로의 암시 적 변환은 없습니다. implicit IndexedSeq to Monoid이 있지만 이는 도움이되지 않습니다.

왜 Seq가 없습니까? 나는 모른다. 아마도 Seq는 monoids/semigroups의 일부 법칙을 위반하므로 변환이 없습니다. 이 서열에 문제가 Scalaz 6 있었다 것 같아 그래서 그들은 일부 기능을 제거했습니다 https://groups.google.com/forum/?fromgroups=#!searchin/scalaz/Seq/scalaz/Deaec1H11W4/gYFSquXjTzYJ

UPDATE

scalaz의 사람들이이 길을 갔다 이유가 더 분명하게 스칼라 문서에서 찾고 있습니다. List은 Seq를 상속받은 LinearSeq를 상속받습니다. IndexedSeq은 Seq. Seq에 대한 세미 그룹을 제공하려는 경우 IndexedSeq 또는 LinearSeq에서 다른 모든 세미 그룹을 재정의하고 둘 사이의 성능 이점을 느슨하게 할 수 있습니다. 당신이 APPEND의 scalaz 서명 보면 당신은 그들이 이러한 성능 차이를 활용할 것을 볼 수있다 : 우리가 깊이 파고 경우

https://github.com/scalaz/scalaz/blob/scalaz-seven/core/src/main/scala/scalaz/std/List.scala

implicit def listMonoid[A]: Monoid[List[A]] = new Monoid[List[A]] { 
    def append(f1: List[A], f2: => List[A]) = f1 ::: f2 
    def zero: List[A] = Nil 
    } 

https://github.com/scalaz/scalaz/blob/scalaz-seven/core/src/main/scala/scalaz/std/IndexedSeq.scala

implicit def ixSqMonoid[A]: Monoid[IxSq[A]] = new Monoid[IxSq[A]] { 
    def append(f1: IxSq[A], f2: => IxSq[A]) = f1 ++ f2 
    def zero: IxSq[A] = empty 
    } 

, 우리가 볼 서열 추가 작업에 대해 :::보다 목록에서 성능이 떨어지는 ++ 만 구현합니다. 그래서 두 번째 질문 인 성과에 대답하십시오. scalaz가 Seq에 대해 semigroup을 구현했다면 색인을 위해 만 최적화 할 수 있기 때문에 모호한 성능으로 이어질 가능성이 높습니다. Iterable에도 같은 문제가 있습니다.

+0

목록에 대한 질문에 대한 중대한 답변. 모든 iterables는 최소한 세미 그룹이어야합니다 ... – coltfred

+0

스칼라 문서를 살펴보면 Seq는 성능 차이가 다른 LinearSeq 및 IndexedSeq의 기본입니다. List는 LinearSeq를 상속하므로 Seq 대신 List 및 IndexedSeq를 선택해야하는 이유를 알 수 있습니다. 이 부분을 더 간결하게 업데이트 할 수 있는지 알게 될 것입니다. – Noah

+0

그건 꽤 좋은 감각, 감사합니다! – coltfred