我想用一个抽象类型Value的限制属于类型类Show的猫科动物.
我的第一次尝试将是这样的:
package examples
import cats._
import cats.data._
import cats.implicits._
class UsingShow1 {
type Value <: Show[Value] // Not sure if this declaration is right
def showValues(vs: List[Value]): String =
vs.map(implicitly[Show[Value]].show(_)).mkString // Error line
}
Run Code Online (Sandbox Code Playgroud)
但是编译器没有找到隐含参数Show[Value].
我知道我可以将前面的例子定义为:
class UsingShow2[Value: Show] {
def showValues(vs: List[Value]): String =
vs.map(implicitly[Show[Value]].show(_)).mkString
}
Run Code Online (Sandbox Code Playgroud)
但是,我想知道是否可以使用抽象类型而不是类型参数.
我有以下代码,我从这里得到:http://underscore.io/blog/posts/2015/06/10/an-introduction-to-cats.html.
import cats.data.Xor
import cats.data.{Validated, Xor}
import cats.syntax.apply._ // For |@| syntax
import cats.std.list._
val v1: ValidatedR = valid(1)
val v2: ValidatedR = invalid(List("Accumulates this"))
val v3: ValidatedR = invalid(List("And this"))
(v1 |@| v2 |@| v3) map { _ + _ + _ }
Run Code Online (Sandbox Code Playgroud)
但是,我得到了:
Cannot resolve symbol |@|
Run Code Online (Sandbox Code Playgroud)
我的build.sbt:
val snapshots = "Sonatype Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
val algebraVersion = "0.2.0-SNAPSHOT"
val catsVersion = "0.1.0-SNAPSHOT"
val algebra = "org.spire-math" %% "algebra" % algebraVersion
val …Run Code Online (Sandbox Code Playgroud) 我写了以下代码
case class Foo(i: Int, j:Int)
def do1() : Reader[Foo, String] = Reader(f => s"doing ${f.i}")
def do2() : Reader[Foo, String] = Reader(f => s"doing ${f.j}")
Run Code Online (Sandbox Code Playgroud)
现在,如果我尝试将这些组成另一个功能
def func() : Reader[Foo, List[String]] = Reader(f =>
for {
m1 <- do1()
m2 <- do2()
} yield List(m1, m2)
}
Run Code Online (Sandbox Code Playgroud)
我希望是我会做的func().run(Foo(10, 20)),这将给我一个List列表("做10","做20")
但我得到编译错误
type mismatch;
found : cats.data.Kleisli[cats.Id,$sess.cmd1.Foo,List[String]]
required: List[String]
m1 <- do1()
^
Compilation Failed
Run Code Online (Sandbox Code Playgroud) 我正在使用Scala创建一个处理固定长度的库.
对于编码和解码,strings我使用基于类型的系统.我提供了自己的Read[A]并Write[A]处理这些行动.
我Write型类使用Show从Cats引擎盖下.它有效,但它要求用户明确导入猫的暗示,如:
import com.github.atais.util.Read._
import cats.implicits._
import com.github.atais.util.Write._
Run Code Online (Sandbox Code Playgroud)
这个例子可以在Github项目上看到:https:
//github.com/atais/Fixed-Length/blob/702d7d242e5b1f6e1c6b581ad7356f36ca6ed8d9/src/test/scala/com/github/atais/fixedlength/simple/CodecTest.scala
有走动吗?我想隐藏cats导入或(如果可能的话)将所有三个合并到一个隐式对象中.
我有以下函数,它做递归:
@tailrec
private def pool[F[_]: Monad, A]
: Consumer[String, String] => (Vector[KkConsumerRecord] => F[A]) => IO[Unit]
= consumer => cb => {
val records: ConsumerRecords[String, String] = consumer.poll(Long.MaxValue)
val converted = records.iterator().asScala.map(rec => {
KkConsumerRecord(rec.key(), rec.value(), rec.offset(), rec.partition(), rec.topic())
})
val vec = converted.foldLeft(Vector.empty[KkConsumerRecord]) { (b, a) =>
a +: b
}
cb(vec)
pool(consumer)(cb)
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨:
[error] /home/developer/Desktop/microservices/bary/kafka-api/src/main/scala/io/khinkali/Consumer/KkConsumer.scala:57:10: type mismatch;
[error] found : org.apache.kafka.clients.consumer.Consumer[String,String]
[error] required: cats.Monad[?]
[error] pool(consumer)(cb)
[error] ^
[error] two errors found
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
我在阅读有关scalaz并注意到,我们可以让列表Applicatives到是Applicative的List.
def sequenceA[F[_]: Applicative, A](list: List[F[A]]): F[List[A]] = list match {
case Nil => (Nil: List[A]).point[F]
case x :: xs => (x |@| sequenceA(xs)) {_ :: _}
}
Run Code Online (Sandbox Code Playgroud)
问题是我们可以做相反的事吗?我们可以改造F[List[A]]成List[F[A]]?
我想解析一个json文件,该文件输出的集合A。的签名Output是IO[List[A]]
我怎样才能将此值转换为Stream:Stream[IO, A]?我可以转换为一个,Stream[IO, List[A]]但不是我想要的
fs2.Stream.eval(input).flatMap(x => fs2.Stream.apply(x))
谢谢
假设我有一个Doobie程序列表(全部带有Unit类型参数,fwiw):
val progList: List[ConnectionIO[Unit]] = prog1 :: prog2 :: ... :: Nil
Run Code Online (Sandbox Code Playgroud)
我有什么办法可以在一个事务中运行它们?理解在这里行不通,因为我只知道运行时程序列表的确切组成。基本上,我想我应该将它们折叠在一起。
我想这个问题通常适用于Cats中的Free Monad,因此我也将Cats标记为。谢谢。
我的技术堆栈是
我试图实现此功能来更新数据库中的行
def update(userId: Long, user: User) = {
(for {
_ <- EitherT(updateUser(userId, user))
user: User <- EitherT(findById(userId))
userProfile: userProfile <- EitherT(userProfileRepository.findById(user.userProfileId))
} yield (user, userProfile).map {
case (user: User, userProfile: UserProfile) =>
val response = new UserResponse(user, userProfile)
Right(response)
case error =>
val str = s"update failure: $error"
Left(str)
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试使用EitherT编译此代码时,我得到了
value withFilter不是cats.data.EitherT的成员
我有一个带有单元测试的无标签最终实现,当我运行单元测试时,仅第一步被调用,其余部分不被调用。
这是测试目标:
class NameThing[F[_]: Monad](implicit console: Console[F]) {
def program: F[Unit] = for {
_ <- console.prompt
rawName <- console.read
fullName = parse(rawName)
_ <- console.display(fullName)
} yield ()
def parse(rawName:String):FullName = {
val parts = rawName.split(" ")
FullName(parts(0), parts(1))
}
}
Run Code Online (Sandbox Code Playgroud)
单元测试是:
implicit object TestConsole extends Console[Test] {
override def prompt: Test[Unit] = {
println("ok1")
Reader(TestEnv => TestEnv.prompt)
}
override def read: Test[String] = {
println("ok2")
Reader(TestEnv => TestEnv.read)
}
override def display(fullName: FullName): Test[Unit] = {
println("ok3")
Reader(TestEnv …Run Code Online (Sandbox Code Playgroud) functional-programming scala for-comprehension reader-monad scala-cats
scala ×10
scala-cats ×10
apache-kafka ×1
applicative ×1
doobie ×1
fs2 ×1
implicit ×1
reader-monad ×1
sbt ×1
scalaz ×1
typeclass ×1