标签: scala-implicits

如何以未来的方式用Scala"pimp my library"?

我使用Scala隐式类来扩展我经常使用的对象.作为一个例子,我有一个类似于Spark上定义的方法DataFrame:

implicit class DataFrameExtensions(df: DataFrame) {
  def deduplicate: Boolean = 
    df.groupBy(df.columns.map(col): _*).count
}
Run Code Online (Sandbox Code Playgroud)

但是如果类已经定义了相同的方法,则不会调用隐式defs.如果我以后升级到定义DataFrame#deduplicate方法的新版Spark,会发生什么?客户端代码将静默切换到新的实现,这可能会导致细微的错误(或明显的错误,这些问题较少).

使用反射,如果在我的隐式定义它之前已经定义,我可以抛出运行时错误.从理论上讲,如果我的隐式方法与现有方法冲突,我可以检测它并重命名我的隐式版本.但是,一旦我升级Spark,运行应用程序并检测问题,使用IDE重命名旧方法为时已晚,因为现在任何引用都引用了本机Spark版本.我将不得不恢复我的Spark版本,通过IDE重命名该方法,然后再次升级.不是世界末日,而是一个伟大的工作流程.DataFramededuplicatedf.deduplicate

有没有更好的方法来处理这种情况?如何安全地使用"皮条客我的图书馆"模式?

scala implicit implicits scala-implicits

11
推荐指数
2
解决办法
368
查看次数

缓存隐式解决方案

为了减少项目的编译时间,我正在缓存某些通过隐式查找解析的类型类.这看起来有些麻烦,因为直接实现不起作用:

scala> implicit val x: String = implicitly[String]
x: String = null
Run Code Online (Sandbox Code Playgroud)

隐式查找将其自己的未初始化定义视为有效实现.A lazy val会以无限递归的方式吹制堆栈.因此,我正在以这种方式处理它:

implicit val x: String = cache.x

object cache {
   val x: String = implicitly[String]
}
Run Code Online (Sandbox Code Playgroud)

但这使得它过于复杂,并且缓存定义不能轻易地使用其他缓存类型(因为它们不是隐式的).

此外,遗憾的是,将值本身隐藏在范围内并不起作用.

scala> :pas
// Entering paste mode (ctrl-D to finish)

object scope {
    implicit val x: String = {
        import scope.{ x => _ }
        implicitly[String]
    }
}

// Exiting paste mode, now interpreting.

defined object scope

scala> scope.x
res0: String = null
Run Code Online (Sandbox Code Playgroud)

是否有更优雅的方法来实现隐式解析缓存?

scala scala-implicits

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

在intellij中处理错误的未使用导入的最佳方法

Intellij错误地标记了一些Scala implicits导入为不使用.有没有办法阻止它在为特定导入明确优化它们时删除那些导入,而不是阻止整个项目的优化导入?

import scala intellij-idea scala-implicits

10
推荐指数
2
解决办法
1979
查看次数

Scala vs Haskell类型类:"catchall"实例

以下Haskell类型类和实例:

class Able a where
  able :: a -> Int

instance Able Int where
  able x = x
Run Code Online (Sandbox Code Playgroud)

通常被翻译成Scala,如下所示:

trait Able[A] {
  def able(a: A): Int
}

implicit object AbleInt extends Able[Int] {
  def able(a: Int) = a
}
Run Code Online (Sandbox Code Playgroud)

在Haskell中,我现在可以定义一种catch-all实例,从而为所有Maybe类型创建一个实例:

instance Able a => Able (Maybe a) where
  able (Just a) = able a
  able Nothing  = 0
Run Code Online (Sandbox Code Playgroud)

这定义的一个实例AbleMaybe Int,Maybe Bool等条件是在一个实例AbleInt,Bool等等.

如何在Scala中做到这一点?

haskell scala implicit typeclass scala-implicits

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

低优先级含义中的歧义

我有以下Scala代码片段:

  import java.io.PrintWriter

  trait Write[-A] {
    def apply(out: PrintWriter)(x: A): Unit
  }

  trait LowPriorityWrites {
    implicit object any extends Write[Any] {
      override def apply(out: PrintWriter)(x: Any) = out.print(x)
    }
  }

  object Write extends LowPriorityWrites {
    implicit def iterable[A](implicit write: Write[A]): Write[Traversable[A]] = new Write[Traversable[A]] {
      override def apply(out: PrintWriter)(xs: Traversable[A]) = {
        xs foreach write(out)
        out.println()
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

基本上,我想要实现的是首先寻找隐含的Write对象.如果不能,回落到默认.toStringAnyLowPriorityWrites.

但是,这种方法不起作用:

ambiguous implicit values:
[error]  both method iterable in object Write of …
Run Code Online (Sandbox Code Playgroud)

scala scala-implicits

6
推荐指数
0
解决办法
438
查看次数

在scala中定义带有两个含义的变量

我在scalaLang的Twitter上发现了一篇有趣的帖子.此代码编译和工作的位置

class A(implicit implicit val b: Int) 

val objA = new A()(42)
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下它是如何工作的?我阅读了implicits的文档,但没有找到这样的案例.请解释一下这里发生了什么.

任何帮助表示赞赏!

scala scala-implicits

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

将函数的隐式转换链接到泛型类

我有以下代码,它应该采用一个函数A => Boolean(输入类型的通用)并Y[A]通过链式隐式转换将其转换为通用特征:

val f: Int => Boolean = ???

trait X[A] {
  def m1: Unit
}
implicit def toX[A](f: A => Boolean): X[A] = ???
f.m1  // Works

trait Y[A] {
  def m2: Unit
}
implicit def toY[T, A](x: T)(implicit toX: T => X[A]): Y[A] = ???
f.m2  // Won't compile
Run Code Online (Sandbox Code Playgroud)

不幸的是,最后一行不会编译.

执行以下任何一项更改就足以使代码编译:

  • 转为X非泛型
  • 转为Y非泛型
  • 输出类型(Int => A)上使用泛型函数替换源类型(在输入类型上是通用函数)
  • 用其他泛型类型替换源类型,例如Option[A],Seq[A]Array[A]

基于此,我的结论是隐式转换链不起作用,因为源类型(输入类型的泛型函数)是通用的和逆变的 …

generics scala implicit-conversion scala-implicits

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

Scala中依赖类型的隐式解析

考虑以下代码:

trait Foo {
  type T
  def value: T
}

object Foo {
  def apply[A](v: A): Foo = new Foo {
    override type T = A
    override def value = v
  }
}

trait Decode[A] {
  def apply(x: A): String
}

object Decode {
  def apply[A](f: A => String): Decode[A] = new Decode[A] {
    override def apply(x: A) = f(x)
  }

  implicit val decodeStr: Decode[String] = Decode(identity)
}

class Sandbox {
  def decodeFoo(foo: Foo)(implicit decoder: Decode[foo.T]): String =
    decoder(foo.value)

  val …
Run Code Online (Sandbox Code Playgroud)

scala implicit typeclass dependent-type scala-implicits

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

如何实现Functor [Dataset]

我奋力关于如何创建的实例Functor[Dataset]...问题是,当你mapABEncoder[B]必须在隐含的范围,但我不知道该怎么做.

implicit val datasetFunctor: Functor[Dataset] = new Functor[Dataset] {
    override def map[A, B](fa: Dataset[A])(f: A => B): Dataset[B] = fa.map(f)
  }
Run Code Online (Sandbox Code Playgroud)

当然这个代码抛出一个编译错误,因为Encoder[B]不可用,但我不能添加Encoder[B]为隐式参数,因为它会改变map方法签名,我该如何解决?

scala apache-spark scala-cats scala-implicits apache-spark-encoders

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

删除对具有单位返回类型的函数的调用时出现奇怪的Scala编译器错误,这怎么可能?

这是一个奇怪的情况:

如果我注释掉feed_usingExplicitTypeClassInstance下面的调用,那么我会收到编译器错误.

非常令人费解.任何解释?

我的意思是,我注释掉一个函数调用(它没有返回任何值),然后代码不再编译?

在理论上这应该是可能的吗?在任何编程语言?

我的意思是我评论出类似的东西println("hello")然后代码不再编译?

当然,如果我将注释掉一个声明或者其他内容,但是调用一个不返回任何内容的函数,那将是可以理解的.

object AnimalFeeder extends App {

  def feed_usingExplicitTypeClassInstance[AnimalInstance]
    (animalTypeClass: AnimalTypeClass[AnimalInstance])
    (food: animalTypeClass.FoodThatAnimalLikes) =
      {
          animalTypeClass.feed(food)
      }

  def feed_usingImplicitTypeClassInstance[AnimalInstance, Food]
    (food: Food)
    (implicit animalTypeClass: AnimalTypeClass.Aux[Food,AnimalInstance]) =
      {
        animalTypeClass.feed(food)
      }


  // If I comment out this line, THEN !, I get an error !!!! How ???
  feed_usingExplicitTypeClassInstance(AnimalTypeClass.CatInstance)(new CatFood())



  feed_usingImplicitTypeClassInstance(new CatFood)

}



trait Food {
  def eat(): Unit
}



trait AnimalTypeClass[AnimalInstance] {
  type FoodThatAnimalLikes <: Food
  def feed(f: FoodThatAnimalLikes) = …
Run Code Online (Sandbox Code Playgroud)

scala dependent-type scala-implicits

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