标签: implicit

通过父类型获取类型类实例

我需要为一堆全部派生自单个特征的案例类提供类型类实例,但据我了解,Scala 编译器需要特定类的实例,并且不会沿继承层次结构上升。所以这段代码:

trait Base

sealed trait Child extends Base

case class Concrete() extends Child

trait Printable[A] {
  def print(value: A): String
}

object WtfTrait {
  def print[A](x: A)(implicit ev: Printable[A]) = {
    println(ev.print(x))
  }

  implicit val printableBase = new Printable[Base] {
    override def print(value: Base): String = value.toString
  }

  val x = Concrete()
  print(x)
}
Run Code Online (Sandbox Code Playgroud)

编译时不会出现错误读取could not find implicit value for parameter ev: Printable[Impl]。有没有办法为基本特征定义单个类型类实例,并通过使用 Shapeless 或其他东西来避免重复。

scala implicit typeclass

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

Scala 从隐式类方法中选择了错误的隐式转换

当隐式类声明中发生转换时,编译器未能选择正确的隐式转换方法。在下面的示例中,我有一个Foo[T]类和一个隐式Helper类,它采用 aFoo并提供一个print方法。该 print 方法调用show,它本身是一个由 on 隐式转换提供的方法Foo

问题是有两种可能的转换提供show:一种转换Foo[T]为 a Bar[T],另一种转换Foo[Array[T]]为 a BarArray[T]。这个想法是,当我们有一个Foo包含数组的时候,我们想要应用更具体的BarArray转换。据我了解,编译器首先选择具有最具体类型的转换。

这在正常上下文中起作用,如下例所示,但print在隐式Helper类中的方法的上下文中中断。在那里,show调用了相同的方法,因此我希望应该应用相同的转换。然而,在这种情况下,编译器总是选择Bar转换,即使它有Foo[Array[T]]并且应该选择BarArray转换。

出了什么问题?

最小失败代码示例:

package scratch

import scala.language.implicitConversions

class Foo[T](val value: T) {}

object Foo {
  implicit def fooToBar[T](foo: Foo[T]): Bar[T] = {
    new Bar(foo.value)
  }

  implicit def fooArrayToBarArray[T](foo: Foo[Array[T]]): BarArray[T] = {
    new …
Run Code Online (Sandbox Code Playgroud)

generics scala implicit implicit-conversion implicit-class

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

为什么Scala编译器可以提供隐式的out of object,但不能提供inside?

标题可能很模糊,但这是代码: https: //github.com/amorfis/why-no-implicit

所以有一个工具可以转化Map[String, Any]为简单的案例类。测试通过了,这段代码说明了它的全部内容:

        case class TargetData(
          groupId: String,
          validForAnalysis: Boolean,
          applicationId: Int
        )

        val map = Map(
          "groupId" -> "123456712345",
          "applicationId" -> 31,
          "validForAnalysis" -> true
        )

        val transformed: TargetData = MapDecoder.to[TargetData](map).transform
Run Code Online (Sandbox Code Playgroud)

这段代码有效。当提供简单的情况时,它很好地创建了案例类实例map

但是,该transform方法必须在“外部”调用 - 就像示例中一样。当我尝试将其移至该MapDecoder.to方法时 - 编译器抱怨缺少隐式。

所以我将代码更改MapDecoder.to为:

def to[A](map: Map[String, Any]) = new MapDecoderH[A](map)
Run Code Online (Sandbox Code Playgroud)

对此:

def to[A](map: Map[String, Any]) = new MapDecoderH[A](map).transform
Run Code Online (Sandbox Code Playgroud)

它停止工作了。这是为什么?为什么在一种情况下提供了隐含的内容,而在另一种情况下则没有提供?所有的变化是我想transform在其他地方调用该方法以MapDecoder.to返回案例类而不是某个转换器。

更新:

to[A]如果我想在要转换的对象内实现方法怎么办?让我们称之为DataFrame,我希望这段代码能够工作:

val df: DataFrame = ... …
Run Code Online (Sandbox Code Playgroud)

scala implicit shapeless

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

Scala隐式转换:2种方式调用

@lucastex 发布了关于Java Elvis操作符的内容,我在Scala中尝试了一些东西以获得相同的效果.

我刚刚将所有内容转换为新的结构类型,?:操作符采用与参数相同类型的对象.所以说:

implicit def toRockStar[B](v : B) = new { 
                            def ?:(opt: => B) = if (v == null) opt else v}
val name: String = "Paulo" // example
Run Code Online (Sandbox Code Playgroud)

为什么name ?: "Lucas"得到"Lucas"name.?:{"Lucas"}得到Paulo?如果它不是null,那么新结构类型应该返回任何东西的初始值,即"Paulo"在上面的代码中.

我有点困惑.任何解释?

scala operators implicit

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

如何定义从类到标量的隐式类型转换?

我有以下代码,它使用我正在编写的库中的Unicode字符串类:

#include <cstdio>
#include "ucpp"
main() {
  ustring a = "test";
  ustring b = "ing";
  ustring c = "- -";
  ustring d;
  d = "cafe\xcc\x81";
  printf("%s\n", (a + b + c[1] + d).encode());
}
Run Code Online (Sandbox Code Playgroud)

ustring类实例的encode方法将内部Unicode转换为UTF-8 char*.但是,因为我无法访问char类定义,所以我不确定如何定义隐式类型转换(因此我在使用printf时不必手动调用encode等).

c++ scalar casting class implicit

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

Scala:'隐式'和类型参数

我在理解以下现象方面遇到了一些麻烦:

trait Trait[A] {
  def traitType: String
}

object Trait {
  implicit val stringTrait: Trait[String] = new Trait[String] {
    def traitType: String = "string"
  }

  implicit val intTrait: Trait[Int] = new Trait[Int] {
    def traitType: String = "int"
  }
}

class Media[A] {
  // works
  def mediaType(implicit t: Trait[A]): String = t.traitType
  // does not compile
  def mediaType: String = implicitly[Trait[A]].traitType
}

object Main {
  def main(args: Array[String]) {
    val a = new Media[String]
    val b = new Media[Int]

    println(a.mediaType) …
Run Code Online (Sandbox Code Playgroud)

generics scala type-inference implicit

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

映射到列表头部时了解Scala Map对象

嗨,我有以下数据,并希望将其映射到第二个参数中的第一项.因此对于:

1 -> List((1,11))
1 -> List((1,1), (1,111))
Run Code Online (Sandbox Code Playgroud)

我想要:

(1,11)
(1,1)
Run Code Online (Sandbox Code Playgroud)

当此数据在RDD中时,我可以执行以下操作:

scala> val m = sc.parallelize(Seq(11 -> List((1,11)), 1 -> List((1,1),(1,111))))
m: org.apache.spark.rdd.RDD[(Int, List[(Int, Int)])] = ParallelCollectionRDD[198] at parallelize at <console>:47

scala> m.map(_._2.head).collect.foreach(println)
(1,11)
(1,1)
Run Code Online (Sandbox Code Playgroud)

但是,当它在Map对象(groupBy的结果)中时,我得到以下内容:

scala> val m = Map(11 -> List((1,11)), 1 -> List((1,1)))
m: scala.collection.immutable.Map[Int,List[(Int, Int)]] = Map(11 -> List((1,11)), 1 -> List((1,1), (1,111)))

scala> m.map(_._2.head)
res1: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1)
Run Code Online (Sandbox Code Playgroud)

当我映射到整个列表时,我得到了我期望的结果,但是当我打电话给它时

scala> m.map(_._2)
res2: scala.collection.immutable.Iterable[List[(Int, Int)]] = List(List((1,11)), List((1,1), (1,111)))
Run Code Online (Sandbox Code Playgroud)

如果我执行以下任一操作,我也可以得到我想要的结果:

scala> m.map(_._2).map(_.head)
res4: …
Run Code Online (Sandbox Code Playgroud)

scala implicit scala-collections scala-implicits

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

Scala:带有/不带()的方法的调用带有可覆盖的含义

这是方法的定义,它ExecutionContext隐式使用,并允许客户端覆盖它.两个执行上下文用于测试它:

val defaultEc = ExecutionContext.fromExecutor(
    Executors.newFixedThreadPool(5))
Run Code Online (Sandbox Code Playgroud)

线程名称如下所示:'pool-1-thread-1'到'pool-1-thread-5'

而斯卡拉的第二个:

scala.concurrent.ExecutionContext.Implicits.global
Run Code Online (Sandbox Code Playgroud)

线程名称如下所示:'scala-execution-context-global-11'

客户端可以覆盖默认隐式通过:

implicit val newEc = scala.concurrent.ExecutionContext.Implicits.global
Run Code Online (Sandbox Code Playgroud)

不幸的是,只有在没有调用带隐式的方法时,它才可以覆盖():

val r = FutureClient.f("testDefault") //prints scala-execution-context-global-11
Run Code Online (Sandbox Code Playgroud)

不工作:

val r = FutureClient.f("testDefault")() //still prints: pool-1-thread-1
Run Code Online (Sandbox Code Playgroud)

问题是为什么它以这种方式工作?因为它使API的客户端变得更加复杂

以下是运行和播放的完整代码:

object FutureClient {
  //thread names will be from 'pool-1-thread-1' to 'pool-1-thread-5'
  val defaultEc = ExecutionContext.fromExecutor(
    Executors.newFixedThreadPool(5))

  def f(beans: String)
           (implicit executor:ExecutionContext = defaultEc)
  : Future[String] = Future {
    println("thread: " + Thread.currentThread().getName)
    TimeUnit.SECONDS.sleep(Random.nextInt(3))
    s"$beans"
  }
}

class FutureTest {
  //prints thread: pool-1-thread-1
  @Test …
Run Code Online (Sandbox Code Playgroud)

overriding scala implicit

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

Scala:如何扩展不可变List

程序的许多方法作为参数接收List [Map [String,String]].

我想通过定义一个类来形式化它并使其更具可读性,例如:

class MyClass extends  List[Map[String, String]]
Run Code Online (Sandbox Code Playgroud)

但是它会抛出一个错误:

Illegal inheritance from sealed class 'List'
Run Code Online (Sandbox Code Playgroud)

有没有正确的方法来处理它?

scala implicit sealed

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

找不到隐式类方法

我有一个带隐式类的对象:

object ModelUtils {
  implicit class RichString(str: String) {
    def isNullOrEmpty(x: String): Boolean = x == null || x.trim.isEmpty
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试使用它时,IntelliJ找不到isNullOrEmpty方法:

"TestString".isNullOrEmpty
Run Code Online (Sandbox Code Playgroud)

我尝试了各种导入导入方法无济于事.我错过了什么?

scala implicit

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