cataquack/cataquack/src/main/scala/tf/bug/example/Example.scala

62 lines
1.7 KiB
Scala

package tf.bug.example
import java.io.File
import cats._
import cats.data._
import cats.implicits._
import cats.effect.IO
import tf.bug.cataquack.{IORaw, Raw, Read, Storage}
import tf.bug.cataquack.implicits._
import scala.io.Source
object Example {
type StringIORaw[T] = IORaw[String, T]
type ReadString[T] = Read[String, T]
def main(args: Array[String]): Unit = {
val f: File = new File("counter.txt")
val s: Storage[StringIORaw, ReadString] = new Storage[StringIORaw, ReadString] {
override def query[T](key: String): StringIORaw[T] = IO {
val s = Source.fromFile(f).getLines()
s.find(_.startsWith(key ++ " ")) match {
case Some(l) => Raw[String, T](l.drop(key.length + 1))
case None => throw new IllegalArgumentException(s"No such key: $key")
}
}
/** Type like IO[List], Id, etc */
override type Output[T] = IO[T]
override def execute[T: ReadString](f: StringIORaw[T]): Output[T] = f.map(_.read)
}
val count = readCount(s)
val desc = readDescription(s)
val pr = for {
c <- count
d <- desc
} yield println(s"${d.read}: ${c.read}")
pr.unsafeRunSync()
}
case class Counter(n: Long)
case class Description(n: String)
def readCount[F[_]: Functor, C[_]](s: Storage[F, C]): F[Long] = {
s.query[Long]("count")
}
def readDescription[F[_]: Functor, C[_]](s: Storage[F, C]): F[String] = {
s.query[String]("desc")
}
implicit def readStringLong: Read[String, Long] = (i: String) => i.toLong
implicit def stringIORawFunctor: Functor[StringIORaw] = new Functor[StringIORaw] {
override def map[A, B](fa: StringIORaw[A])(f: A => B): StringIORaw[B] = fa.map(a => rawFunctor[String].map(a)(f))
}
}