21

Comonad とは何か、Scala 構文で記述できれば教えてください。scalazライブラリの実装を見つけましたが、それがどこで役立つかは明確ではありません。

4

3 に答える 3

12

モナドを使えば、モナドに値を追加したり、非モナドからモナドへの計算に基づいて値を変更したりできます。コモナドを使用すると、それらから値を抽出し、計算に基づいてコモナドから非コモナドに変更できます。

自然な直感は、CM[A] があり、A を抽出したい場所に通常現れるということです。

comonads に少しさりげなく触れているこの非常に興味深い投稿を参照してください。ただし、少なくとも私にとっては、それらを非常に明確にしています。

于 2012-06-19T23:04:33.887 に答える
7

以下は、このブログ投稿のコードの直訳です。

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)

出力:

 | | | | | | | | | | | | | | | | | | | |#| | | | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | | | |#|#| | | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | | | |#| |#| | | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | | | |#|#|#|#| | | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | | | |#| | | |#| | | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | | | |#|#| | |#|#| | | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | | | |#| |#| |#| |#| | | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | | | |#|#|#|#|#|#|#|#| | | | | | | | | | | |
 | | | | | | | | | | | | | | | | | | | |#| | | | | | | |#| | | | | | | | | | |
 | | | | | | | | | | | | | | | | | | | |#|#| | | | | | |#|#| | | | | | | | | |
 | | | | | | | | | | | | | | | | | | | |#| |#| | | | | |#| |#| | | | | | | | |
 | | | | | | | | | | | | | | | | | | | |#|#|#|#| | | | |#|#|#|#| | | | | | | |
 | | | | | | | | | | | | | | | | | | | |#| | | |#| | | |#| | | |#| | | | | | |
 | | | | | | | | | | | | | | | | | | | |#|#| | |#|#| | |#|#| | |#|#| | | | | |
 | | | | | | | | | | | | | | | | | | | |#| |#| |#| |#| |#| |#| |#| |#| | | | |
 | | | | | | | | | | | | | | | | | | | |#|#|#|#|#|#|#|#|#|#|#|#|#|#|#|#| | | |
 | | | | | | | | | | | | | | | | | | | |#| | | | | | | | | | | | | | | |#| | |
 | | | | | | | | | | | | | | | | | | | |#|#| | | | | | | | | | | | | | |#|#| |
 | | | | | | | | | | | | | | | | | | | |#| |#| | | | | | | | | | | | | |#| |#|
 | | | | | | | | | | | | | | | | | | | |#|#|#|#| | | | | | | | | | | | |#|#|#|#
于 2012-06-19T22:13:32.253 に答える