标签: scala-cats

是什么 ?类型?

我正在尝试为Monad具有多个类型参数的类型实现cat 实例.我看着猫的Either实例,看看它是如何在那里完成的.Either Monad来自猫的部分实例代码复制如下:

import cats.Monad

object EitherMonad {
  implicit def instance[A]: Monad[Either[A, ?]] =
    new Monad[Either[A, ?]] {
      def pure[B](b: B): Either[A, B] = Right(b)

      def flatMap[B, C](fa: Either[A, B])(f: B => Either[A, C]): Either[A, C] =
        fa.right.flatMap(f)
    }
}
Run Code Online (Sandbox Code Playgroud)

它无法编译错误: error: not found: type ?

什么是?类型,如何在为自己的类型创建实例时使用它?

scala scala-cats

6
推荐指数
1
解决办法
314
查看次数

以功能方式进行多个API调用

通过使用Scala和Cats(或者可能是另一个专注于类别理论和/或函数式编程的库),以最具功能性(代数)的方式解决这个问题的最佳方法是什么?

资源

如果我们有以下方法执行REST API调用来检索单个信息?

type FutureApiCallResult[A] = Future[Either[String, Option[A]]]

def getNameApiCall(id: Int): FutureApiCallResult[String]
def getAgeApiCall(id: Int): FutureApiCallResult[Int]
def getEmailApiCall(id: Int): FutureApiCallResult[String]
Run Code Online (Sandbox Code Playgroud)

如您所见,它们会产生异步结果.Either monad用于在API调用期间返回可能的错误,而Option用于在API未找到资源时返回None(这种情况不是错误,而是可能的和期望的结果类型).

以功能方式实现的方法

case class Person(name: String, age: Int, email: String)

def getPerson(id: Int): Future[Option[Person]] = ???
Run Code Online (Sandbox Code Playgroud)

如果任何API调用失败或任何API调用返回None(整个Person实体无法组合),则此方法应使用上面定义的三个API调用方法异步组合并返回Person或None.

要求

出于性能原因,所有API调用必须以并行方式完成

我猜

我认为最好的选择是使用Cats Semigroupal Validated但是在尝试处理Future和如此多的嵌套Monads时我迷路了:S

任何人都可以告诉我你将如何实现这一点(即使改变方法签名或主要概念)或指向我正确的资源?我在编码时对Cats和Algebra很新,但我想学习如何处理这种情况,以便我可以在工作中使用它.

functional-programming scala category-theory scala-cats

6
推荐指数
2
解决办法
1686
查看次数

将列表转换为猫ValidatedNel

鉴于:

def convert[T](list: List[Either[String, T]]): Validated[NonEmptyList[String], NonEmptyList[T]] =
  NonEmptyList.fromList(list)
    .toRight("list is empty")
    .flatMap(...
Run Code Online (Sandbox Code Playgroud)

我如何平面图NonEmptyList[Either[String, T]]最终我最终得到了我的Validated回报值?

cats库中有什么可以解释这种情况吗?或者我是否需要手动执行以下操作:将Eithers列表转换为列表之一的最佳方法?

scala scala-cats

6
推荐指数
1
解决办法
795
查看次数

cats-effect:如何将`List [IO]`转换为`IO [List]`

我创建了一个列表,IO[Unit]以便从URL列表中检索数据.但现在我如何将它转换回单一IO[Unit]

io scala scala-cats

6
推荐指数
2
解决办法
2319
查看次数

应用于列表中的Cats.sequence错误

我想转换List[Either[String, Int]]en 的列表Either[String, List[Int]].为此,我想使用Cats.sequence:

/* for ammonite users
interp.load.ivy("org.typelevel" %% "cats-core" % "1.0.1")

@
*/

import cats.instances.list._
import cats.instances.either._
import cats.syntax.traverse._

val seqCorrect: List[Either[String, Int]] = List(Right(1), Right(2), Right(3))

val result1 = seqCorrect.sequence
Run Code Online (Sandbox Code Playgroud)

但是我有以下错误:

Cannot prove that Either[String,Int] <:< G[A].
val result1 = seqCorrect.sequence
                         ^
Run Code Online (Sandbox Code Playgroud)

我发现错误消息非常无益.我该如何解决这个问题?

scala scala-cats

6
推荐指数
1
解决办法
634
查看次数

Cats中的效果抽象和并行执行

我有下一个使用Cats IO编写的代码,它并行执行多个动作(简化):

import cats.effect._
import cats.implicits._

import scala.concurrent.ExecutionContext.Implicits.global

    class ParallelExecIO {

        def exec: IO[List[String]] = {
            val foo = IO.shift *> IO("foo")
            val bar = IO.shift *> IO("bar")
            List(foo, bar).parSequence
        }
    }
Run Code Online (Sandbox Code Playgroud)

是否可以使用效果抽象重写此代码?应提供哪些类型的证据?

样品:

class ParallelExecIO[F[_]: ConcurrentEffect /* ??? */] {

    def exec: F[List[String]] = {
        val foo = Async.shift[F](implicitly) *> "foo".pure[F]
        val bar = Async.shift[F](implicitly) *> "bar".pure[F]
        List(foo, bar).parSequence 
    }
}
Run Code Online (Sandbox Code Playgroud)

[error] value parSequence不是List [F [String]]的成员

functional-programming scala scala-cats

6
推荐指数
1
解决办法
887
查看次数

在Doobie中并行运行查询

是否可以使用Doobie并行运行多个查询?

我有以下(伪)查询:

def prepareForQuery(input: String): ConnectionIO[Unit] = ???
val gettAllResults: ConnectionIO[List[(String, BigDecimal)]] = ???
def program(input : String) : ConnectionIO[List[(String, BigDecimal)]] = for{
    _ <- prepareForQuery(input)
    r <- gettAllResults
  } yield r
Run Code Online (Sandbox Code Playgroud)

我尝试了以下内容:

import doobie._
import doobie.implicits._
import cats.implicits._
val xa = Transactor.fromDataSource[IO](myDataSource)
val result = (program(i1),program(i2)).parMapN{case (a,b) => a ++ b}
val rs = result.transact(xa).unsafeRunSync
Run Code Online (Sandbox Code Playgroud)

但是,找不到的NonEmptyParallel实例ConnectionIO

错误:(107,54)找不到参数p的隐式值:cats.NonEmptyParallel [doobie.ConnectionIO,F] val结果=(program(i1),program(i2))。parMapN {case(a,b)= > a ++ b}

我是否缺少明显的东西或尝试无法完成的事情?谢谢

functional-programming scala scala-cats doobie

6
推荐指数
1
解决办法
266
查看次数

什么是商店在scalaz

我试图理解Lenses scalaz(令人惊讶的是没有发现类似的东西cats-core)我遇到了所谓Store的类型别名:

type StoreT[F[_], A, B] = IndexedStoreT[F, A, A, B]
type IndexedStore[I, A, B] = IndexedStoreT[Id, I, A, B]
type Store[A, B] = StoreT[Id, A, B]
Run Code Online (Sandbox Code Playgroud)

哪里

final case class IndexedStoreT[F[_], +I, A, B](run: (F[A => B], I))
Run Code Online (Sandbox Code Playgroud)

问题是如何对待这种类型?文档只是引用了Lenses.用几句话就可以解释一下吗?

对我来说,它看起来类似于Statemonad,其中"状态转换"存储功能F[A => B]

functional-programming scala scalaz scala-cats

6
推荐指数
1
解决办法
153
查看次数

如何在cats-effect的资源中添加适当的错误处理

我正在尝试使用cats-effect以纯粹的功能方式获取一些基本文件IO(写入/读取)。遵循教程之后,下面就是我读取文件的内容:

private def readFile(): IO[String] = for {
  lines <-  bufferedReader(new File(filePath)).use(readAllLines)
} yield lines.mkString

def bufferedReader(f: File): Resource[IO, BufferedReader] =
  Resource.make {
    IO(new BufferedReader(new FileReader(f)))
  } { fileReader =>
    IO(fileReader.close()).handleErrorWith(_ => IO.unit)
  }
Run Code Online (Sandbox Code Playgroud)

现在在handleErrorWith函数中,我可以记录发生的任何错误,但是如何为它添加适当的错误处理(例如,返回Resource[IO, Either[CouldNotReadFileError, BufferedReader]])?

functional-programming scala scala-cats cats-effect

6
推荐指数
1
解决办法
236
查看次数

如何从Async [IO]创建Async [Future]

我正在尝试在doobie存储库的代码中隐式添加Async和Sync。Sync和Async [F]可以正常工作IO。我想将它们转换为未来并面临问题

我试图从IO创建自己的Aync

def futureAsync(implicit F: MonadError[Future, Throwable]): Async[Future] = new Async[Future] {
    override def async[A](k: (Either[Throwable, A] => Unit) => Unit): Future[A] = IO.async(k).unsafeToFuture()

    override def asyncF[A](k: (Either[Throwable, A] => Unit) => Future[Unit]): Future[A] =
      throw new Exception("Not implemented Future.asyncF")

    override def suspend[A](thunk: => Future[A]): Future[A] = thunk

    override def bracketCase[A, B](acquire: Future[A])(use: A => Future[B])(release: (A, ExitCase[Throwable]) => Future[Unit]): Future[B] =
      throw new Exception("Not implemented Future.bracketCase")

    override def raiseError[A](e: Throwable): Future[A] = F.raiseError(e)

    override def handleErrorWith[A](fa: Future[A])(f: Throwable …
Run Code Online (Sandbox Code Playgroud)

scala scala-cats doobie

6
推荐指数
1
解决办法
558
查看次数