我有以下代码.我必须确认它是如何工作的方式.任何人都可以为此提供解释
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知道吗?
我有一个简单的特性,要求实现有一个quality(x:A)我想要返回的方法Ordered[B].换句话说,quality转换A为Ordered[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的类来定义.需要使用这些函数来计算品质因数.这可以是一种 …
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可用的实例作为方法的参数.
我半预计将不能够从发现的隐式转换死Bar到Foo,由于fooFromBar不是从一个简单的函数Foo来Bar,但我读的这个问题是隐式转换可以有隐含参数,实际上编译器似乎有部分出来了.
我发现了另一个问题,详细解答了Scala寻找填充内容的地方.但它只证实了我之前的理解:Scala在直接范围内首先看起来,然后是其他一些与此无关的地方. …
我在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.
我正在尝试将数据类型通用编程的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 编译器使用的隐式搜索优先级和算法。在上面的列表中,直接导入的隐式函数应该比关联类型中的作用域具有更高的优先级(例如在伴随对象中定义)
这条规则大部分时间都有意义,直到直接导入的 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 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)
根据这篇文章:
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)