gpt4 book ai didi

scala - 如何使用 IO monad 编写猫的理解力

转载 作者:行者123 更新时间:2023-12-03 17:29:48 24 4
gpt4 key购买 nike

我有以下代码:

import cats.effect.IO
import cats.data.State
import cats.data.StateT
import cats.implicits._
import cats.effect.LiftIO

abstract class Example {
object implicits {
implicit def myEffectLiftIO: LiftIO[IOGameplay] =
new LiftIO[IOGameplay] {
override def liftIO[A](ioa: IO[A]): IOGameplay[A] = {
StateT.liftF(ioa)
}
}
}

type Gameplay[A] = State[GameState, A]
type IOGameplay[A] = StateT[IO, GameState, A]
type EitherDirection[A] = Either[Throwable, A]

type Map = Array[Array[FieldType]]
sealed trait FieldType
case class GameState(map: Map, block: Block)
case class Block(f1: Field, f2: Field)
case class Field()

import implicits._
val L = implicitly[LiftIO[IOGameplay]]

sealed trait GameResult
sealed trait Direction

trait IOMonad {
def println(msg: String): IO[Unit]
def readln(): IO[String]
}

def play(io: IOMonad): StateT[IO, GameState, GameResult] = {
val L = implicitly[LiftIO[IOGameplay]]

for {
// print map to the console
_ <- L.liftIO(io.println("Next move: "))
directionOpt <- L.liftIO(readDirection(io))
direction <- StateT.liftF[IO, GameState, Direction](IO.fromEither(directionOpt))
nextBlock <- IO(nextBlock(direction))
gameResult <- calculate(nextBlock)
} yield {
gameResult
}
}

def readDirection(io: IOMonad): IO[EitherDirection[Direction]]
def nextBlock(direction: Direction): Gameplay[Block]
def calculate(block: Block): Gameplay[GameResult]
}

这并不完全准确,但我发布了整个 block 来解释问题。
在这里,我对值进行了许多转换以产生 IO 并将其转换为 StateT。有没有更聪明的方法来做到这一点?也许我应该以某种方式将 io 任务与主要算法分开,即与这个理解分开?或者我应该这样做吗?

最佳答案

一个问题是您的 Gameplay类型与 IOGameplay 不兼容, 自 Gameplay使用 Eval单子(monad)。我假设你想要这个:

    type Gameplay[F[_], A] = StateT[F, GameState, A]
type IOGameplay[A] = Gameplay[IO, A]

这些方法需要返回 IOGameplay实例(或者您可以稍后在程序中解除它们):

    def nextBlock(direction: Direction): IOGameplay[Block]
def calculate(block: Block): IOGameplay[GameResult]

然后 for-comprehension 编译并稍作调整:

      for {
// print map to the console
_ <- L.liftIO(io.println("Next move: "))
directionOpt <- L.liftIO(readDirection(io))
direction <- StateT.liftF[IO, GameState, Direction](IO.fromEither(directionOpt))
nextBlock <- nextBlock(direction)
gameResult <- calculate(nextBlock)
} yield {
gameResult
}

顺便说一句, IO 的预期目的是什么?在这个程序中的效果?用户输入?

关于scala - 如何使用 IO monad 编写猫的理解力,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56828739/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com