2012-06-19 3 views
19

Comonad가 가능한 경우 스칼라 구문으로 설명합니다. 라이브러리 구현이 scalaz인데 유용 할 수있는 곳이 명확하지 않습니다.스칼라의 Comonad 예제

+1

참고 사항 : [하스켈의 Comonad typeclass 란 무엇입니까?] (http://stackoverflow.com/questions/8428554/what-is-the-comonad-typeclass-in-haskell). 스칼라즈는 일반적으로 가능한 한 하스켈 - 쉐 (Haskell-ish)로 만들려고 노력하기 때문에 블로그 게시물이 도움이 될 수 있습니다. –

+0

또한보십시오 : 최근 reddit 포스트/r/haskell [Comonads에 대한 표기법] (http://www.reddit.com/r/haskell/comments/v6ik6/a_notation_for_comonads_orchard_mycroft_pdf/) –

답변

12

글쎄, 모나드는 당신이 그들에게 값을 추가 모나드에 비 모나드에서 계산에 기반을 변경할 수 있습니다. Comonads는 당신이 그들로부터 값을 추출하고, comonad에서 non-comonad까지의 계산을 기반으로 값을 바꿀 수있게합니다.

자연 직관은 보통 날에, 당신은이 CM [A]와

A를 추출 조금 부담 comonads에 접촉 this 매우 흥미로운 게시물을 참조 할이 곳 나타나지만 것이 오 최소한, 그것들을 아주 분명하게 만든다.

+0

"자연스러운 직감이란 보통 CM [A]가 있고 A를 추출하려고하는 위치에 나타납니다." 그건'Copointed' /'Copure'입니다. W [A] => (W [A] => B) => W [B]') 또는'cojoin' ('W [A] => W [A]] '), 당신은'Comonad'를 얻는다. – missingfaktor

+0

@missingfaktor 나는 그들을 정의하지 않고있다. Stas가 이미 그 정의를 본 것으로 가정한다. 나는 보통 이런 상황에서 코모 나드가 발견 될 것이라고 말하고있다. –

7

다음은 블로그 게시물 this의 코드를 리터럴 변환 한 것입니다.

case class U[X](left: Stream[X], center: X, right: Stream[X]) { 
    def shiftRight = this match { 
    case U(a, b, C#:: cs) => U(b #:: a, c, cs) 
    } 

    def shiftLeft = this match { 
    case U(a #:: as, b, c) => U(as, a, b #:: c) 
    } 
} 

// Not necessary, as Comonad also has fmap. 
/* 
implicit object uFunctor extends Functor[U] { 
    def fmap[A, B](x: U[A], f: A => B): U[B] = U(x.left.map(f), f(x.center), x.right.map(f)) 
} 
*/ 

implicit object uComonad extends Comonad[U] { 
    def copure[A](u: U[A]): A = u.center 
    def cojoin[A](a: U[A]): U[U[A]] = U(Stream.iterate(a)(_.shiftLeft).tail, a, Stream.iterate(a)(_.shiftRight).tail) 
    def fmap[A, B](x: U[A], f: A => B): U[B] = U(x.left.map(f), x.center |> f, x.right.map(f)) 
} 

def rule(u: U[Boolean]) = u match { 
    case U(a #:: _, b, C#:: _) => !(a && b && !c || (a == b)) 
} 

def shift[A](i: Int, u: U[A]) = { 
    Stream.iterate(u)(x => if (i < 0) x.shiftLeft else x.shiftRight).apply(i.abs) 
} 

def half[A](u: U[A]) = u match { 
    case U(_, b, c) => Stream(b) ++ c 
} 

def toList[A](i: Int, j: Int, u: U[A]) = half(shift(i, u)).take(j - i) 

val u = U(Stream continually false, true, Stream continually false) 

val s = Stream.iterate(u)(_ =>> rule) 

val s0 = s.map(r => toList(-20, 20, r).map(x => if(x) '#' else ' ')) 

val s1 = s.map(r => toList(-20, 20, r).map(x => if(x) '#' else ' ').mkString("|")).take(20).force.mkString("\n") 

println(s1) 

출력 :

| | | | | | | | | | | | | | | | | | | |#| | | | | | | | | | | | | | | | | | | 
| | | | | | | | | | | | | | | | | | | |#|#| | | | | | | | | | | | | | | | | | 
| | | | | | | | | | | | | | | | | | | |#| |#| | | | | | | | | | | | | | | | | 
| | | | | | | | | | | | | | | | | | | |#|#|#|#| | | | | | | | | | | | | | | | 
| | | | | | | | | | | | | | | | | | | |#| | | |#| | | | | | | | | | | | | | | 
| | | | | | | | | | | | | | | | | | | |#|#| | |#|#| | | | | | | | | | | | | | 
| | | | | | | | | | | | | | | | | | | |#| |#| |#| |#| | | | | | | | | | | | | 
| | | | | | | | | | | | | | | | | | | |#|#|#|#|#|#|#|#| | | | | | | | | | | | 
| | | | | | | | | | | | | | | | | | | |#| | | | | | | |#| | | | | | | | | | | 
| | | | | | | | | | | | | | | | | | | |#|#| | | | | | |#|#| | | | | | | | | | 
| | | | | | | | | | | | | | | | | | | |#| |#| | | | | |#| |#| | | | | | | | | 
| | | | | | | | | | | | | | | | | | | |#|#|#|#| | | | |#|#|#|#| | | | | | | | 
| | | | | | | | | | | | | | | | | | | |#| | | |#| | | |#| | | |#| | | | | | | 
| | | | | | | | | | | | | | | | | | | |#|#| | |#|#| | |#|#| | |#|#| | | | | | 
| | | | | | | | | | | | | | | | | | | |#| |#| |#| |#| |#| |#| |#| |#| | | | | 
| | | | | | | | | | | | | | | | | | | |#|#|#|#|#|#|#|#|#|#|#|#|#|#|#|#| | | | 
| | | | | | | | | | | | | | | | | | | |#| | | | | | | | | | | | | | | |#| | | 
| | | | | | | | | | | | | | | | | | | |#|#| | | | | | | | | | | | | | |#|#| | 
| | | | | | | | | | | | | | | | | | | |#| |#| | | | | | | | | | | | | |#| |#| 
| | | | | | | | | | | | | | | | | | | |#|#|#|#| | | | | | | | | | | | |#|#|#|# 
+0

'Comonad'에 대한 가져 오기가 없습니다. '= >>'과'|>'도 정의되어 있지 않습니다. – EnverOsmanov

+0

@EnverOsmanov,이 게시물은 코드 스 니펫에 가져 오기를 포함하는 중요성을 인식하지 못한 때부터입니다. :-) 어쨌든, Scalaz는 이후로 크게 변했고 패키지에는 여러 차례의 조직 개편이있었습니다. 나는 새로운 Scalaz (또는 고양이, 그것이 당신의 독약 인 경우) 당이 게시물을 업데이트 할 수 있다면 고맙겠습니다. – missingfaktor