标签: given

使用 Scala cats 编写 MTL 风格代码的给定实例的问题

我正在尝试编写一些 Scala 代码以实现mtl 风格的自定义行为。例如,为了公开对特定效果进行抽象的“写入数据库”功能,我编写了自己的类型类:

trait CanPersist[M[_]]:
  def persistToDB[A](a: A): M[Unit]

given CanPersist[IO] with
  def persistToDB[A](a: A): IO[Unit] = IO(???) // Write to DB
Run Code Online (Sandbox Code Playgroud)

IO 实例可以轻松实现,但我感兴趣的是自动为任何基于 IO 的 monad 堆栈提供实例:

// If a Transformer wraps a Monad that can persist then it can persist too
given persistTA[M[_]: CanPersist: Monad, T[_[_], _]: MonadTransformer]:
  CanPersist[[A] =>> T[M, A]] with 
  def persistToDB[A](a: A): T[M, Unit] =
    summon[MonadTransformer[T]].lift(summon[CanPersist[M]].persistToDB(a))
Run Code Online (Sandbox Code Playgroud)

问题显然是 cats 没有定义自己的MonadTransformer类型类;幸运的是,自己编写非常简单:

trait MonadTransformer[T[_[_], _]]:
  def lift[M[_]: Monad, A](ma: M[A]): T[M, A] …
Run Code Online (Sandbox Code Playgroud)

functional-programming scala monad-transformers scala-cats given

7
推荐指数
1
解决办法
460
查看次数

Scala3“as”和“with”关键字与“given”一起使用

目前正在学习 Scala 3 隐式,但我很难理解 \xe2\x80\x8baswith关键字在如下定义中的作用:

\n
given listOrdering[A](using ord: Ordering[A]) as Ordering[List[A]] with\n \xe2\x80\x8bdef compare(a: List[A], b: List[A]) = ...\n
Run Code Online (Sandbox Code Playgroud)\n

我尝试谷歌搜索,但没有找到任何好的解释。我已经检查了 Scala 3 参考指南,但我发现的唯一一件事as是它是一个“软修饰符”,但这并不能真正帮助我理解它的作用......我猜as在上面的代码以某种方式用于澄清这listOrdering[A]是一个Ordering[List[A]](就像正在进行某种类型的打字或类型转换?),但如果能找到它背后的真正含义那就太好了。

\n

至于with,我只在 Scala 2 中使用它来继承多个特征(class A extends B with C with D),但在上面的代码中,它似乎以不同的方式使用......

\n

非常感谢任何解释或为我指明查看文档的正确方向!

\n

另外,如果用 Scala 2 编写上面的代码会是什么样子?也许这可以帮助我弄清楚发生了什么事......

\n

syntax scala implicit scala-3 given

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

如何召唤“给定”成员?

假设我有一些类型类

trait FooBar[X]
Run Code Online (Sandbox Code Playgroud)

和一个实例FooBar[Int]

given intIsFooBar: FooBar[Int] = new FooBar {}
Run Code Online (Sandbox Code Playgroud)

现在,假设我有一个Intf具有某种成员类型的接口A,并且还保证有一个given FooBar[A]

trait Intf:
  type A
  given aIsFoobar: FooBar[A]
Run Code Online (Sandbox Code Playgroud)

现在,我有了类型Int,也有一个FooBar[Int],但是我如何实际实现这个接口呢Int

如果我尝试

class IntImpl() extends Intf:
  type A = Int
  given aIsFoobar: FooBar[A] = summon
Run Code Online (Sandbox Code Playgroud)

然后我收到“函数体 IntImpl.aIsFoobar 中的无限循环”错误,因为summon似乎看到的是aIsFoobar而不是intIsFooBar

如果我尝试使用summon某些辅助辅助变量中的实例,如下所示:

class IntImpl() extends Intf:
  type A = Int
  private final val _aIsFoobar: FooBar[A] = summon
  given aIsFoobar: …
Run Code Online (Sandbox Code Playgroud)

scala implicit initialization-order scala-3 given

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

隐藏的错误与给定的时间和匹配。Perl 真的是跨平台的吗?

我一直在尝试制作一个相对较大的 Perl 程序,多年来它在 CentOS 上运行得非常好,但现在却可以在 Ubuntu 上运行,但这已经成为一个巨大的噩梦。CentOS 使用为 x86_64-linux-thread-multi 构建的 Perl,Ubuntu 使用 x86_64-linux-gnu-thread-multi 构建。AFAIK,当程序调用相同的先前版本时,解释器行为在两种环境中应该相同v5.10.1。然而,我得到了非常不同的行为,包括关于given/whensmartmatch正在进行实验的警告,最重要的是,一系列难以追踪和解决的令人讨厌的错误。given当下面所示的语句(表 1)匹配并调用函数时,会出现一个特定问题。$ailtype然后突然间,从未被触及的switch 变量(称为 )的值从内存中删除了!如果我简单地调用该函数,就不会发生任何令人讨厌的事情。因此,我用语句(表格 2)替换了given/when用法,我的问题是为什么问题仍然出现?!真正避免该问题的唯一形式是简单的/链(形式 3),这清楚地表明问题出在形式 1 和 2 以及 perl 解释器不一致且充满错误的情况下:它甚至不产生“表 2 的实验性警告。forifelsif

这是表格 1(原件):

print "ailtype is $ailtype \n"; # prints "ailtype is 8"

given ($ailtype) {
    when (4) { &parse_mascot}
    when (5) { &parse_sequest}
    when (8) { &parse_spectrast($ms2_results, $rttemp)}
    when (9) { &parse_cnstab($ms2_results, …
Run Code Online (Sandbox Code Playgroud)

perl match switch-statement given

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

为什么编译器不能链式转换?

T1, T2, T3三种类型。我们还定义了该类的两个给定实例Conversion,以便编译器可以从T1toT2和从T2to进行转换T3

下面的代码可以正常编译:

type T1
type T2
type T3

given Conversion[T1, T2] with
    override def apply(x: T1): T2 = ???

given Conversion[T2, T3] with
    override def apply(x: T2): T3 = ???

val t1: T1 = ???
val t2: T2 = t1
val t3: T3 = t2
Run Code Online (Sandbox Code Playgroud)

但是当我们尝试从T1到 时会发生什么T3?编译器不会让我们:

val t3: T3 = t1
             ^^
             Found:    (t1: T1)
             Required: T3
Run Code Online (Sandbox Code Playgroud)

我的问题:编译器无法本机(参见解决方法)链转换是否有特定原因?

我的解决方法 …

scala implicit type-conversion scala-3 given

0
推荐指数
1
解决办法
52
查看次数