相关疑难解决方法(0)

Scala中的隐式类

我有以下代码.我必须确认它是如何工作的方式.任何人都可以为此提供解释

object Implicits
{
  implicit class RichSeq[A](val xs:Seq[A])
  {
    def mapD[B](function:A => B):Seq[B] = xs.map(function)
  }
}
Run Code Online (Sandbox Code Playgroud)

这就像地图上的抽象,我可以使用序列.因此,如果我导入此Implicits.RichSeq,我可以使用任何Seq [A]上的方法,因为这会将Seq [A]转换为RichSeq [A].

import Implicits.RichSeq._
val xs:Seq[Int] = Seq(22,33)
val output:Seq[Int] = xs.mapD(_+22)
Run Code Online (Sandbox Code Playgroud)

我想知道它是如何工作的,因为当我在Seq [A]类型上使用mapD时,它将搜索从Seq [A]到RichSeq [A]的隐式转换.它会找到这个隐式转换,因为这是一个隐式类?

它是否将隐式类扩展为:

隐式def RichSeq [A](val xs:Seq [A])= new RichSeq(xs)

我想它可能在里面做这些东西.对此ne1知道吗?

functional-programming scala

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

从Scala中的方法返回Ordered [T]

我有一个简单的特性,要求实现有一个quality(x:A)我想要返回的方法Ordered[B].换句话说,quality转换AOrdered[B].这样我可以比较B.

我有以下基本代码:

trait Foo[A] {
    def quality[B](x:A):Ordered[B]

    def baz(x1:A, x2:A) = {
       // some algorithm work here, and then
       if (quality(x1) > quality(x2)) {
           // some stuff
       }
}
Run Code Online (Sandbox Code Playgroud)

我想实现如下:

class FooImpl extends Foo[Bar] {
    def quality(x:Bar):Double = {
       someDifficultQualityCalculationWhichReturnsADouble
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为这可以工作,因为如果我是正确的,Double隐式转换为RichDouble实现Ordered[Double].
但是在特征>baz方法中它给了我一个quality(x2)说明的错误:Type mismatch, expected Nothing, actual Ordered[Nothing]

我不明白这一点,因为,来自C#,我发现它可以与返回类似的东西相比IEnumerable<A>,然后使用一个很好的扩展方法IEnumerable.

我在这里错过了什么?我想要的特性是在trait中定义一个复杂的算法,但是关键函数需要由实现trait的类来定义.需要使用这些函数来计算品质因数.这可以是一种 …

sorting types scala

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

方法参数可以作为隐式转换的隐式参数吗?

REPL会话中的以下代码:

case class Foo(x : Int)

case class Bar(x : Int)

case class Converter(y : Int) {
    def convert(x : Int) = x + y
}

implicit def fooFromBar(b : Bar)(implicit c : Converter) = Foo(c convert (b x))

def roundaboutFoo(x : Int, converter : Converter) : Foo = Bar(x)
Run Code Online (Sandbox Code Playgroud)

给我这个错误:

错误:找不到参数c的隐含值:转换器def roundaboutFoo(x:Int,converter:Converter):Foo = Bar(x)

如果它不明显(暗示),我正在尝试做的是Bar(x)隐式转换为a Foo.隐式转换本身虽然是通过隐式参数化的Converter.我想要使​​用此转换的时间都有一个Converter可用的实例作为方法的参数.

我半预计将不能够从发现的隐式转换死BarFoo,由于fooFromBar不是从一个简单的函数FooBar,但我读的这个问题是隐式转换可以有隐含参数,实际上编译器似乎有部分出来了.

我发现了另一个问题,详细解答了Scala寻找填充内容的地方.但它只证实了我之前的理解:Scala在直接范围内首先看起来,然后是其他一些与此无关的地方. …

scala implicit

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

使模型能够将自身转换为JSON

我在http://www.playframework.com/documentation/2.2.x/ScalaJsonRequests上运行了JSON文档,但没找到我需要的东西.我需要的是让我的类能够像这样转换为JSON:

# model
case class MyClass(a: Int, b: String ....)

# controller

def myAction = Action {
  val myClass = getMyClass()
  Ok(toJson(myClass))
}
Run Code Online (Sandbox Code Playgroud)

所以无论我在哪里调用Ok(toJson(myClass)),它都会自行转换为JSON.我怎样才能做到这一点?

PS对不起,我忘了提到MyClass java.util.UUID作为一个Id和其他一些类作为一个字段:

case class MyClass(id: UUID, a: Int, b: String, c: MyClass2 ....)
Run Code Online (Sandbox Code Playgroud)

因此Json.writes[MyClass],至少不会起作用UUID.

json scala playframework playframework-2.2

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

Scala:隐式类的多个类型参数

我正在尝试将数据类型通用编程的Haskell库的一部分移植到Scala.这是我遇到的问题:

我已经Generic使用一些容器类型参数定义了一个特征:

trait Generic[G[_]] {
     // Some function declarations go here
 }
Run Code Online (Sandbox Code Playgroud)

现在我有一个抽象类,Collect有三个类型参数和一个函数声明(它表示一种类型,而不是可以从类型结构中将所有类型的子类收集B到一个类型的容器中):F[_]A

abstract class Collect[F[_],B,A] {
  def collect_ : A => F[B]
}
Run Code Online (Sandbox Code Playgroud)

为了使其延伸通用,前两个类型参数F[_]B给出,并且A是咖喱(这种效果是使用类型lambda表达式模拟的):

class CollectC[F[_],B] extends Generic[({type C[A] = Collect[F,B,A]})#C] {
    // Function definitions go here
}
Run Code Online (Sandbox Code Playgroud)

问题是我需要最后一个类定义是隐式的,因为稍后在我的代码中我将需要能够编写像

class GUnit[G[_]](implicit gg: Generic[G]) {
    // Some definitions
}
Run Code Online (Sandbox Code Playgroud)

当我只是前面implicit的类定义时,我得到一个错误说implicit classes must accept exactly one primary constructor parameter.有谁遇到过类似的问题?有没有一种已知的解决方法?我目前没有看到如何在保持相同功能的同时重构代码,所以欢迎任何建议.提前致谢!

scala implicit generic-programming

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

在 Scala 中,是否可以阻止编译器首先搜索 Predef 隐式?

这个帖子:

Scala 在哪里寻找隐式?

描述了现代 Scala 编译器使用的隐式搜索优先级和算法。在上面的列表中,直接导入的隐式函数应该比关联类型中的作用域具有更高的优先级(例如在伴随对象中定义)

这条规则大部分时间都有意义,直到直接导入的 Predef.scala 开始干扰:

    case class A(v: Int)

    object A {

      implicit class AFns(self: A) {

        def +(v2: Int): A = A(self.v + v2)
      }
    }

    val a1 = A(3)

    val b = a1 + 4

    assert(b == A(7))
Run Code Online (Sandbox Code Playgroud)

上面的示例应该可以成功编译,但是 Predef 中定义的所有类的 + 运算符覆盖主导了场景,并导致所有带有 + 运算符的扩展无用(除非在更严格的范围内明确导入)。这很烦人,有没有办法在 Predef 中禁用隐式或“降级”其优先级?

以上实验已在scala 2.12.12 & 2.13.3中进行

scala implicit scala-compiler

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

在 Scala 2.13 中,为什么伴随对象的隐式作用域有时可能会错位?如何纠正?

下面是一个测试 scala 2.13 编译器隐式特性的简单示例:

object OverridingScope {

  trait System {

    trait Handler[T]
  }

  object Sys1 extends System {

    object Handler {

      implicit def handle1: Handler[Int] = new Handler[Int] {}
    }

    implicit def handle2: Handler[Long] = new Handler[Long] {}
  }
}
Run Code Online (Sandbox Code Playgroud)

根据这篇文章:

Scala 在哪里寻找隐式?

Handler当使用 type 时,trait 的伴生对象可以作为隐式作用域的一部分自动导入Handler[_],外部对象Sys1应该是无关紧要的。这意味着 handle1 应该是可见的,而 handle2 应该是隐藏的。

但是下面的测试用例显示了完全相反的情况:

class OverridingScope extends BaseSpec {

  import OverridingScope._

  it("implicits in companion is in scope") {

//    val hh = implicitly[Sys1.Handler[Int]]
    // Doesn't work
  } …
Run Code Online (Sandbox Code Playgroud)

scala implicit typeclass companion-object

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