2014-07-15 2 views
5

현재 스칼라에서 스칼라즈 스타일로 일부 코드를 이식하고 있습니다.스칼라즈 바인딩 [Seq] typeclass

구체적인 코드 (예 : List, Vector)보다는 노출 된 API 서명에서 Seq 특성을 사용하는 것이 일반적입니다. 그러나 Scalaz는 Bind [Seq] typeclass의 구현을 제공하지 않기 때문에 Scalaz에 몇 가지 문제점을 제기합니다.

즉 올바르게 작동합니다.

List(1,2,3,4) >>= bindOperation 

하지만이 오류와 함께 실패하지

Seq(1,2,3,4) >>= bindOperation 

could not find implicit value for parameter F0: scalaz.Bind[Seq]

나는이 Scalaz에서 의도적 인 디자인 결정 가정 - 그러나 선행하는 방법에 대한 구성/모범 사례에 대한 확신입니다 .

더 유연한 Seq 인터페이스 대신 List/Vector에 직접 코드를 직접 작성해야합니까? 아니면 단순히 내 자신의 Bind [Seq] typeclass를 정의해야합니까?

+1

그러나, 'IndexedSeq'의 모나드 인스턴스가 있습니다. – rightfold

답변

11

컬렉션 라이브러리는 특정 유형 (목록,지도 등)에 map을 사용하면 동일한 유형을 다시 가져옵니다. an extremely complex inheritance hierarchy과 함께 CanBuildFrom과 같은 유형 클래스를 사용하여이를 관리합니다. 그것은 일을 끝낸다 (적어도 틀림없이), 그러나 복잡성은 매우 원칙을 느끼지 않는다. 그것은 엉망입니다. 많은 사람들이 그것을 싫어합니다.

복잡성은 일반적으로 라이브러리 사용자로서는 피하기 쉽지만 라이브러리 디자이너에게는 악몽입니다. Seq에 대한 모나드 인스턴스를 제공하면 모든 사용자 유형이 모나드 작업을 사용하는 모든 유형 Seq으로 계층 구조 위로 올라 갔음을 의미합니다.

Scalaz의 사람들이 대부분 Scalaz가 hierarchy- List, Vector의 잎 주위에 남아 있도록, 어쨌든, 매우 하위 유형 좋아하지 않는 경향 등 당신은 예를 들어,이 결정 on the mailing list의 논의를 볼 수 있습니다.

처음 Scalaz를 사용하기 시작했을 때 Seq 등의 인스턴스를 제공하려고 시도한 많은 유틸리티 코드를 작성하여 CanBuildFrom과 함께 사용할 수 있도록했습니다. 그때 나는 멈 췄고, 이제 Scalaz를 따라 가면서 List, Vector, MapSet을 내 코드로 사용하는 경향이 있습니다. "Scalaz style"에 전념한다면 Scalaz 자신의 IList, ISet, ==>> 등을 채택해야합니다. 하지만 모범 사례에 대한 명확한 합의를 찾지는 못하지만 두 가지 접근 방식 모두 작동하도록 만들 수 있으므로 원하는 것을 찾기 위해 실험을 해보면됩니다.

+1

이 또한 이유가 무엇입니까? 'scalaz.NonEmptyList [T]'는'Seq [T]'의 하위 유형이 아닙니까? – rightfold

+1

@rightfold : 예, 언젠가 'NonEmptyList'가 언젠가 불변 될 경우 너무 놀라지 않을 것입니다. 이것은 Seq swamp에서 멈추지 않는 또 다른 이유입니다. –