cats

モナドトランスフォーマー (1)

ListとList[Option]とOptionの共存 val intList: List[Int] = List(1, 2, 3, 5) val strOptList: List[Option[String]] = List(Some("a"), Some("c"), None, Some("d")) val option: Option[Int] = Option(1) val t: OptionT[List, (Int, String, Int)] = fo…

プログラミングhaskell 9章 version scala 〜後半(ライフゲーム)〜

type Board = List[Pos] val width: Int = 5 val height: Int = 5 def showcells(b: Board): IO[Unit] = seqn(b.map(p => writeat(p)("○"))) def isAlive(b: Board)(p: Pos): Boolean = b.contains(p) def isEmpty(b: Board)(p: Pos): Boolean = !isAlive(b)…

Stateモナドの使い道 [フィボナッチ]

case class S(current: Int, next: Int) { def process() = S(next, current + next) } val fib: Stream[State[S, Int]] = Stream.continually(State(s => (s.process(), s.current))) val state: State[S, Stream[Int]] = fib.take(15).sequence println(st…

プログラミングhaskell 9章 version scala 〜後半〜

val box: List[String] = List( "+---------------+", "| |", "+---+---+---+---+", "| q | c | d | = |", "+---+---+---+---+", "| 1 | 2 | 3 | + |", "+---+---+---+---+", "| 4 | 5 | 6 | - |", "+---+---+---+---+", "| 7 | 8 | 9 | * |", "+---+---+---…

プログラミングhaskell 9章 version scala 〜前半〜

def getChar: IO[Char] = IO(System.in.read().toChar) def putChar(c: Char): IO[Unit] = IO(print(c)) def echo: IO[Unit] = for { c <- getChar _ <- putChar('\n') _ <- putChar(c) _ <- putChar('\n') } yield () def getLine: IO[List[Char]] = for { …

Writerモナドの使い道 [自作モノイド]

case class Product(money: Int) case class Coins(gohyakuen: Int, hyakuen: Int, gojuen: Int, juen: Int) { def +(other: Coins) = Coins(gohyakuen + other.gohyakuen, hyakuen + other.hyakuen, gojuen + other.gojuen, juen + other.juen) def sum(): …

Writerモナドの使い道 [実行回数]

def hoge(): Writer[Int, String] = for { _ <- Writer.tell(1) r <- Writer.value[Int, String]("hoge") } yield r val w: Writer[Int, List[String]] = List.range(0, 100).map(_ => hoge()).sequence println(w.run) // (hoge()実行回数, 結果のリスト)

Writerモナドの使い道 [ログ出力]

def selectIdFromDb(): Writer[List[String], Int] = for { _ <- Writer.tell(List("db access start.")) _ <- Writer.tell(List("TODO: db access 実装")) r <- Writer.value[List[String], Int](1) _ <- Writer.tell(List("db access end.")) } yield r de…

プログラミングhaskell 8章 version scala 〜後半〜

前半はこちら def token[T](p: Parser[T]): Parser[T] = for { _ <- space v <- p _ <- space } yield v def identifier: Parser[String] = token(ident) def natural: Parser[Int] = token(nat) def symbol(s: String): Parser[String] = token(string(s)) …

プログラミングhaskell 8章 version scala 〜前半〜

type Parser[T] = StateT[Option, String, T] def pure[T](x: T): Parser[T] = StateT.pure[Option, String, T](x) def failure: Parser[String] = StateT[Option, String, String](_ => None) def item: Parser[String] = StateT{ case "" => None case xs …

Validated(Applicative)のsequence

ListのEitherのsequenceは最初のエラーだけしかかえってこない。 ListのValidatedのsequenceはすべてのエラーがかえってくる。 val eithers: List[Either[String, Int]] = List(Right(1), Left("error1"), Right(2), Left("error2"), Right(3)) val validate…

Readerモナドの使い道 [DI]

catsを使用したReaderモナドの使い道例として、DIのサンプル trait DbAccessor { def select: List[String] def count: Int } object DbAccessorImpl extends DbAccessor { override def select: List[String] = { // TODO: dbAccess処理 List.empty } overr…