标签: scala-cats

猫用mapN验证

我是Cats的初学者.验证猫有错误.我使用这样的列表累加器:

case class Type(
 name: String,
 pattern: String,
 primitiveType: PrimitiveType = PrimitiveType.string,
 sample: Option[String] = None,
 comment: Option[String] = None,
 stat: Option[Stat] = None
) {
 type ValidationResult[A] = Validated[List[String], A]

 def checkValidity(): ValidationResult[Boolean] = {
  val errorList: mutable.MutableList[String] = mutable.MutableList.empty

  val patternIsValid = Try {
   primitiveType match {
    case PrimitiveType.struct =>
    case PrimitiveType.date =>
      new SimpleDateFormat(pattern)
    case PrimitiveType.timestamp =>
      pattern match {
        case "epoch_second" | "epoch_milli" =>
        case _ if PrimitiveType.formatters.keys.toList.contains(pattern) =>
        case _ =>
          DateTimeFormatter.ofPattern(pattern)
      }
    case _ …
Run Code Online (Sandbox Code Playgroud)

scala scala-cats

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

在 doobie 中为 for-comprehension 编写可选查询?

我想在 doobie 中使用 for-comprehension 在一个事务中运行多个查询。就像是:

def addImage(path:String) : ConnectionIO[Image] = {
  sql"INSERT INTO images(path) VALUES($path)".update.withUniqueGeneratedKeys('id', 'path')
}

def addUser(username: String, imageId: Optional[Int]) : ConnectionIO[User] = {
  sql"INSERT INTO users(username, image_id) VALUES($username, $imageId)".update.withUniqueGeneratedKeys('id', 'username', 'image_id')
}

def createUser(username: String, imagePath: Optional[String]) : Future[User] = {
  val composedIO : ConnectionIO[User] = for {
    optImage <- imagePath.map { p => addImage(p) }
    user <- addUser(username, optImage.map(_.id))
  } yield user

  composedIO.transact(xa).unsafeToFuture
}
Run Code Online (Sandbox Code Playgroud)

我刚开始接触 doobie(和猫),所以我对 FreeMonads 不太熟悉。我一直在尝试不同的解决方案,但为了理解工作,看起来两个块都需要返回一个cats.free.Free[doobie.free.connection.ConnectionOp,?]。

如果这是真的,有没有办法将我的 ConnectionIO[Image](来自 addImage 调用)转换为 cat.free.Free[doobie.free.connection.ConnectionOp,Option[Image]] ?

scala free-monad scala-cats doobie

5
推荐指数
1
解决办法
1193
查看次数

使用 cat-effect 的 IO monad 进行单元测试

情景

在我目前正在编写的应用程序中,我在IOApp中使用了cat -effect 的IO monad

如果从命令行参数“debug”开始,我会将我的程序流委派到一个调试循环中,该循环等待用户输入并执行各种与调试相关的方法。一旦开发者在enter没有任何输入的情况下按下,应用程序将退出调试循环并退出 main 方法,从而关闭应用程序。

此应用程序的主要方法大致如下所示:

import scala.concurrent.{ExecutionContext, ExecutionContextExecutor}
import cats.effect.{ExitCode, IO, IOApp}
import cats.implicits._

object Main extends IOApp {

    val BlockingFileIO: ExecutionContextExecutor = ExecutionContext.fromExecutor(blockingIOCachedThreadPool)

    def run(args: List[String]): IO[ExitCode] = for {
        _ <- IO { println ("Running with args: " + args.mkString(","))}
        debug = args.contains("debug")
        // do all kinds of other stuff like initializing a webserver, file IO etc.
        // ...
        _ <- if(debug) debugLoop else IO.unit
    } yield …
Run Code Online (Sandbox Code Playgroud)

java unit-testing scala scala-cats

5
推荐指数
1
解决办法
2821
查看次数

ConcurrentHashMap 与函数式编程。暂停 unsafeRun 安全吗?

unsafeRunSync问题:使用暂停是否安全IO?例如

val io: IO[Unit] = //...
val io2: IO[Unit] = IO(io.unsafeRunSync)
Run Code Online (Sandbox Code Playgroud)

我这样做的原因是我有一些参数化的类,F[_]: Effect它就像一个缓存:

import cats.effect.Effect

final class MyChache[F[_]](implicit F: Effect[F]) {
  private val cache = new ConcurrentHashMap[Int, String]

  def getOrCreate(key: Int): F[String] = F delay {
    cache.computeIfAbsent(
      key, 
      k => longRunningEffecfulComputation(k).toIO.unsafeRunSync() // <-- Here
    )
  }
}


object MyCache {
  def longRunningEffecfulComputation[F[_] : Effect](key: Int): F[String] = {
    //...
  }
}
Run Code Online (Sandbox Code Playgroud)

重点是我只想为每个键运行一次长时间运行的有效计算(这是相当罕见的)。然而,我希望在检索现有密钥时保持非阻塞。

ConcurrentHashMap似乎是一个完美的选择,但它需要这种带有运行和暂停效果的丑陋技巧。还有更好的方法吗?

concurrency functional-programming scala scala-cats

5
推荐指数
1
解决办法
637
查看次数

Scala、cats、http4s - 无法识别来自 Http4s 的 &lt;+&gt; 符号

我创建了两条Http4s路线:

class FirstRoutes[F[_] : Async](service: FirstService[F]) extends Http4sDsl[F] {        
  def routes: HttpRoutes[F] = HttpRoutes.of[F] {
        //... some code
  }
}   

class SecondRoutes[F[_] : Async] extends Http4sDsl[F] {            
    def routes: HttpRoutes[F] = HttpRoutes.of[F] {
    //... some code
    }
}
Run Code Online (Sandbox Code Playgroud)

现在在我的main方法中,我想这样称呼这条路线:

override def run(args: List[String]): IO[ExitCode] =
    for {
      _ <- {
        val app = {
          //...
          val firstRoutes = new FirstRoutes[F](someService)
          val secondRoutes = new SecondRoutes[F]
          (firstRoutes.routes <+> secondRoutes.routes).orNotFound
        }
Run Code Online (Sandbox Code Playgroud)

但是当我编译这段代码时,我得到了一个错误:

Error:(26, 33) value <+> is not …
Run Code Online (Sandbox Code Playgroud)

scala scala-cats http4s

5
推荐指数
2
解决办法
1158
查看次数

Scala-cats:记忆化支持

Scalaz 提供 Memo 用于记忆。我希望 scala-cats 也有类似的解决方案。一般来说,我有不同方法的特征:

trait t {
  def f1:Int = ???
  def f2(i:Int):Int = ???
  def f3(i:Int, s:String):String = ???
}
Run Code Online (Sandbox Code Playgroud)

如果 Casts 支持此类解决方案,请举例说明如何:

  1. 使用它来记忆所有以前定义的方法,以防可以修改源?

  2. 如何将其应用于外部代码,将记忆注入到客户端的调用中,而不触及现有服务

  3. 如何控制记忆的生命周期?一般来说,我需要保留每笔交易的结果。控制它的策略是什么?例子也会很棒!

scala memoization scala-cats

5
推荐指数
0
解决办法
347
查看次数

Doobie - 将任意效果提升到 ConnectionIO 中

我正在尝试在使用 Doobie 将用户插入数据库的同一事务中发送电子邮件。
我知道我可以举IOConnectionIO通过使用Async[ConnectionIO].liftIO(catsIO)其中catsIO: IO[String]
但在我的代码,我不上工作IO,我使用F与约束,例如F[_]: Async 于是我可以代替F我自己的单子进行测试。

是否可以在不直接使用类型的情况下以某种方式提升F[String]进入? ConnectionIO[String]IO

这是我为 IO 类型找到的答案:Doobie and DB access composition within 1 transaction

scala scala-cats doobie cats-effect

5
推荐指数
1
解决办法
1202
查看次数

flatMap 忽略结果

我想知道是否存在一个函数(在 scala 或猫中)忽略flatMap. 例如

Some("ignore this").ignoreArgumentFlatMap(Some("result"))
Run Code Online (Sandbox Code Playgroud)

这将与

Some("ignore this").flatMap(_ => Some("result"))
Run Code Online (Sandbox Code Playgroud)

monads scala scala-cats

5
推荐指数
1
解决办法
253
查看次数

在函数参数级别实现 Ad hoc 多态性(混合不同类型的参数)

当我在 Scala 中有一个函数时:

def toString[T: Show](xs: T*): String = paths.map(_.show).mkString
Run Code Online (Sandbox Code Playgroud)

以及范围内的以下类型类实例:

implicit val showA: Show[MyTypeA]
implicit val showB: Show[MyTypeB]
Run Code Online (Sandbox Code Playgroud)

我可以通过toString以下方式使用函数:

val a1: MyTypeA
val a2: MyTypeA
val stringA = toString(a1, a2)

val b1: MyTypeB
val b2: MyTypeB
val stringB = toString(b1, b2)
Run Code Online (Sandbox Code Playgroud)

但我不能叫toString混合型的参数MyTypeAMyTypeB

// doesn't compile, T is inferred to be of type Any
toString(a1, b1)
Run Code Online (Sandbox Code Playgroud)

是否有可能以toString一种可以混合不同类型的参数(但仅限于Show类型类可用)的方式重新定义?

请注意,我知道 cat show interpolator 可以解决这个特定的例子,但我正在寻找一种也可以应用于不同情况的解决方案(例如toNumber)。

我也知道通过.show在将参数传递给toString …

polymorphism scala implicit typeclass scala-cats

5
推荐指数
2
解决办法
158
查看次数

为什么具有 Monad 实例的类型的 Semigroupal 不组合?

我正在尝试将我的头围绕在 Cats 中的 Semigroupals 上。以下是 Underscore 的“Scala with Cats”中的陈述。

cats.Semigroupal 是一个允许我们组合上下文的类型类

trait Semigroupal[F[_]] {
  def product[A, B](fa: F[A], fb: F[B]): F[(A, B)]
}
Run Code Online (Sandbox Code Playgroud)

参数fafb彼此独立:在将它们传递给 之前,我们可以按任一顺序计算它们product。这与 形成对比flatMap,后者对其参数施加了严格的顺序。

所以基本上,我们也应该能够结合两个Either上下文,但这似乎不起作用:

import cats.instances.either._ 

type ErrorOr[A] = Either[Vector[String], A]

Semigroupal[ErrorOr].product(Left(Vector("Error 1")), Left(Vector("Error 2")))

// res3: ErrorOr[Tuple2[Nothing, Nothing]] = Left(Vector("Error 1"))
Run Code Online (Sandbox Code Playgroud)

如果 semigroupal 的 USP 急切地执行独立操作,则必须在传递给之前对两者进行评估product,但我们无法获得组合结果。

我们可能期望product应用于Either累积错误而不是快速失败。同样,也许令人惊讶的是,我们发现它product实现了与 相同的 fail?fast 行为flatMap

这是否与使用替代方法能够组合任何相同类型的上下文的原始前提相悖?

为了确保一致的语义,Cats 的 Monad(它扩展了 Semigroupal)根据map …

scala scala-cats

5
推荐指数
1
解决办法
68
查看次数