Skip to content

Instantly share code, notes, and snippets.

@yasuabe
Created December 25, 2018 10:40
Show Gist options
  • Save yasuabe/4dcb04f64ce1f91085dd184334b360be to your computer and use it in GitHub Desktop.
Save yasuabe/4dcb04f64ce1f91085dd184334b360be to your computer and use it in GitHub Desktop.
import cats.{Functor, Monoid, Representable}
import cats.instances.stream._
import cats.syntax.representable._
implicit val rep: Representable[Stream] { type Representation = Int } = new Representable[Stream] {
def F: Functor[Stream] = implicitly[Functor[Stream]]
type Representation = Int
def tabulate[A](f: Int => A) = {
def loop(n: Int): Stream[A] = f(n) #:: loop(n + 1)
loop(0)
}
def index[A](f: Stream[A]): Int => A = f.apply
}
val index = Stream.continually(Stream('a', 'b', 'c')).flatten.index
(5 until 10) map (n => s"$n:${index(n)}") // Vector(5:c, 6:a, 7:b, 8:c, 9:a)
val tabulate = ((n: Int) => ('a' + (n % 3)).toChar).tabulate
tabulate.take(5).toList // List(a, b, c, a, b)
type Triple[A] = (A, A, A)
implicit val functorTriple: Functor[Triple] = new Functor[Triple] {
def map[A, B](fa: (A, A, A))(f: A => B): (B, B, B) = (f(fa._1), f(fa._2), f(fa._3))
}
implicit val repTriple = new Representable[Triple] {
type Representation = Int
def F = Functor[Triple]
def index[A](f: Triple[A]): Int => A = n =>
if (n < 0) f._1
else if (n > 0) f._3
else f._2
def tabulate[A](f: Int => A): Triple[A] = F.map(-1, 0, 1)(f)
}
val triple: Triple[Symbol] = ('minus, 'zero, 'plus)
(-10 to 10 by 5) map triple.index
val g = (n: Int) => if (n < 0) '-' else if (n > 0) '+' else '0'
g.tabulate[Triple]
g.tabulate[Triple].index.apply(10)
val monad = Representable.monad[Triple]
monad.pure('x')
monad.flatMap(('x', 'y', 'z'))(a => (s"1$a", s"2$a", s"3$a"))
val monAdd: Monoid[Int] = new Monoid[Int] {
def empty: Int = 0
def combine(x: Int, y: Int): Int = x + y
}
val monMul: Monoid[Int] = new Monoid[Int] {
def empty: Int = 1
def combine(x: Int, y: Int): Int = x * y
}
val bmAdd = Representable.bimonad[Triple, Int](repTriple, monAdd)
val bmMul = Representable.bimonad[Triple, Int](repTriple, monMul)
bmAdd.extract(('x', 'y', 'z'))
bmMul.extract(('x', 'y', 'z'))
bmAdd.coflatMap(('x', 'y', 'z'))(t => s"$t")
bmMul.coflatMap(('x', 'y', 'z'))(t => s"$t")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment