我是一名强大的Java开发人员,他最近开始尝试在我的空闲时间内学习Scala.我正在通过scala-lang.org中的示例 PDF来阅读Scala,并且很困惑第一个示例中的快速排序是如何工作的.这是代码:
object QuickSort extends App {
def sort(input: Array[Int]): Array[Int] = {
if(input.length <= 1) input
else
{
val pivot = input(input.length / 2)
Array.concat(
sort(input filter (pivot >)),
input filter (pivot ==),
sort(input filter (pivot <))
)
}
}
sort(Array(5, 4, 3, 2, 1)) foreach println
}
Run Code Online (Sandbox Code Playgroud)
我的问题不是语法或任何东西,但我对过滤函数的来源感到困惑.根据PDF,它说它来自Seq [T]类,并且所有数组都是Seq [T]的实例.这一切都很好,花花公子,在阅读PDF时,我很满意,也是一位非常开心的新手Scala开发人员.但后来我深入挖掘并开始查看Array [T]的scaladoc以及Array [T]的源代码,我不知道Array [T]类是如何扩展或继承Seq [T]特征的所有.我错过了什么?
大家好 请原谅我在Scala上提出一个愚蠢的问题.虽然我已经在Scala中编程了大约2年,但我仍然觉得很难理解其implicit用法.我们来举一个讨论的例子:
Array(1,2,3,4).map(x => x)
Run Code Online (Sandbox Code Playgroud)
如果你查看scaladoc,你就无法map在Array课堂上找到这个方法.map可以应用的原因是在Array(1,2,3,4)中implicit def intArrayOps (xs: Array[Int]): ArrayOps[Int]定义了隐式函数scala.Predef.
但是,有两个参数列表,第二个参数列表写为implicit bf: CanBuildFrom[Array[T], B, That]).现在我不知道该编译器发现一个适当的参数类型CanBuildFrom申请时map上Array(1,2,3,4).
我正在尝试一组自定义容器函数,并从Scala的集合库中获取有关CanBuildFrom[-From, -Elem, -To]隐式参数的灵感.
在Scala的集合中,CanBuildFrom支持返回类型函数的参数化map.在内部,CanBuildFrom参数像工厂一样使用:map在它的输入元素上应用它的第一个顺序函数,将每个应用程序的结果提供给CanBuildFrom参数,最后调用CanBuildFrom的result方法来构建调用的最终结果map.
在我的理解中,-From类型参数CanBuildFrom[-From, -Elem, -To]仅用于apply(from: From): Builder[Elem, To]创建Builder具有一些元素的预初始化.在我的自定义容器函数中,我没有那个用例,所以我创建了自己的CanBuildFrom变体Factory[-Elem, +Target].
现在我可以有一个特质 Mappable
trait Factory[-Elem, +Target] {
def apply(elems: Traversable[Elem]): Target
def apply(elem: Elem): Target = apply(Traversable(elem))
}
trait Mappable[A, Repr] {
def traversable: Traversable[A]
def map[B, That](f: A => B)(implicit factory: Factory[B, That]): That =
factory(traversable.map(f))
}
Run Code Online (Sandbox Code Playgroud)
和实施 Container
object Container …Run Code Online (Sandbox Code Playgroud) 我是Scala的新手,并且一直在努力学习和理解隐式转换和参数,并遇到了一个令我感到困惑的场景.
对于上下文,我使用Scaldi在Akka应用程序中执行依赖注入,并希望有多个可注入的actor从抽象类继承.我相信我无法使抽象类成为一个特征,因为我们需要Injector通过构造函数参数使隐式可用来利用框架.
展示我所看到的行为的一个非常人为的例子如下:
class SecretSauce {}
abstract class Base(implicit secretSauce: SecretSauce) {}
class Concrete extends Base {}
object Example extends App {
... // Setup Actor system, etc, etc
implicit val secretSauce: SecretSauce = new SecretSauce()
}
Run Code Online (Sandbox Code Playgroud)
我期待一些工作,但我得到一个编译错误:
Unspecified value parameter secretSauce.
class Concrete extends Base {
^
Run Code Online (Sandbox Code Playgroud)
如果我将隐式参数添加到具体类中,就像这样,事情可行:
class Concrete(implicit secretSauce: SecretSauce) extends Base {}
Run Code Online (Sandbox Code Playgroud)
我认为我的困惑源于隐式参数如何工作 - 在我所描述的情况下,它们是不是由子类继承的?有人可以ELI5在我的例子中发生了什么或指向我可以帮助清理的参考?
谢谢!
case class Cat(name: String)
object CuterImplicits {
implicit class CatCuteChecker(c: Cat) {
def isCute(c: Cat) = true
}
}
trait CuteChecker[A] {
def isCute(a: A): Boolean
}
object CheckingForCuteness {
def isItCute[A](a: A) = implicitly[CuteChecker[A]].isCute(a)
}
object Main extends App {
CheckingForCuteness.isItCute[Cat](Cat("funny"))
}
Run Code Online (Sandbox Code Playgroud)
怎么修:
错误:(17,37)找不到参数e的隐含值:CuteChecker [A] def isItCute [A](a:A)=隐式[CuteChecker [A]].isCute(a)^
拿这个代码:
class Register(var value:Int = 0) {
def getZeroFlag() : Boolean = (value & 0x80) != 0
}
object Register {
implicit def reg2int(r:Register):Int = r.value
implicit def bool2int(b:Boolean):Int = if (b) 1 else 0
}
Run Code Online (Sandbox Code Playgroud)
我想这样使用它:
val x = register.getZeroFlag + 10
Run Code Online (Sandbox Code Playgroud)
但我受到了欢迎:
type mismatch; found : Boolean required: Int
Run Code Online (Sandbox Code Playgroud)
怎么了?我是否需要定义一个隐式的函数返回一个bool?
我使用scala 2.10.0-snapshot日期(20120522)并具有以下Scala文件:
这个定义了类型类和基本的类型类实例:
package com.netgents.typeclass.hole
case class Rabbit
trait Hole[A] {
def findHole(x: A): String
}
object Hole {
def apply[A: Hole] = implicitly[Hole[A]]
implicit val rabbitHoleInHole = new Hole[Rabbit] {
def findHole(x: Rabbit) = "Rabbit found the hole in Hole companion object"
}
}
Run Code Online (Sandbox Code Playgroud)
这是包对象:
package com.netgents.typeclass
package object hole {
def findHole[A: Hole](x: A) = Hole[A].findHole(x)
implicit val rabbitHoleInHolePackage = new Hole[Rabbit] {
def findHole(x: Rabbit) = "Rabbit found the hole in Hole package object"
}
}
Run Code Online (Sandbox Code Playgroud)
这是测试: …
令我惊讶的是,我发现编译器无法解析以下示例中的隐含:
trait API {
def f(implicit a: Int) = ???
}
class Impl extends API {
implicit val int = 2
}
(new Impl).f
Run Code Online (Sandbox Code Playgroud)
以及在
class Impl extends API
object Impl {
implicit val int = 2
}
Run Code Online (Sandbox Code Playgroud)
我对此深感沮丧.为什么会这样,是否有解决方法?我必须注意,将隐式导入到外部作用域不是一个选项,因为上述的唯一目的是隐藏用户的实现细节Impl.
以上是API的实现者提供特定类型类实例的模式的摘要,这些实例被API中实现的函数使用.最终用户使用这些实现.
问题陈述:
我阅读了多篇文章/文章,这些文章暗示了scala编译的时间
我想删除/减少它们到最小可能看到没有它们的编译时间会是什么样的(代码库是基于scalaz&akka&slick的各种复杂性的大约1000个文件)
我真的不知道我可以执行什么样的静态分析.对现有工具的任何赞美/引用都非常赞赏.
请考虑以下代码:
class A { def print = println("A") }
class B extends A { override def print = println("B") }
def foo(implicit a: A) = a.print
def bar(implicit a: A) = {
implicit val b = new B
foo
}
bar(new A) // B
Run Code Online (Sandbox Code Playgroud)
我很奇怪,为什么呼吁foo在bar不提出一个ambiguous implicit values错误.当然
implicit val b: A = new B
Run Code Online (Sandbox Code Playgroud)
会引起这个错误.为什么foo选择隐式b而非隐式a?或者甚至更一般:将采取什么规则?
编辑:
由于我与Ivan的评论 - 我想澄清:如果我以与隐式方法参数相同的方式命名本地隐式val,我会知道我的问题的答案.
def bar(implicit a: A) = {
implicit val a …Run Code Online (Sandbox Code Playgroud)