从各方面Source来看,斯卡拉有点乱 - 我读过的所有内容都提到资源尚未开放,神秘的错误......
我想知道Scala的最新版本是否仍然如此,如果是这样,有什么值得的选择?
我大多听说过scala-io和scalaz-streams(显然是标准的Java IO原语).我错过了什么吗?如果有人有这些或其他项目的经验,他们各自的利弊是什么?
我倾向于选择scala-io,因为我发现作者的博客是一个相当高质量的信息来源,但我想更多地了解替代品以及其他人使用的内容.
在构建时抛出异常通常被视为不太礼貌的事情,但我不确定在尝试对case类值强制执行约束时如何避免这种情况.
比如说我需要表示一个范围,并且两个边界必须是正的.立即实施将是:
case class Range(from: Int, to: Int)
Run Code Online (Sandbox Code Playgroud)
然而,这并没有确保这两个from和to是积极的,也不是to大于from.
我的第一直觉是按如下方式实施:
case class Range(from: Int, to: Int) {
require(from >= 0)
require(to >= 0)
require(to >= from)
}
Run Code Online (Sandbox Code Playgroud)
然而,这使得Range构造函数不安全.
是否存在一种通用模式来保持案例类的易用性,强制实施值约束并避免抛出异常?
我理解null在Scala中不赞成,并且应该始终将可选值包装在一个Option(或"null类型",如果有的话).
优点很明显,永远不需要检查null值,并且生成的代码更安全,更舒适.
然而,在实践中,没有什么可以阻止价值null- 规则不是由编译器强制执行的,而是更多的绅士协议.例如,在与Java API交互时,这很容易破坏.
这是最好的做法吗?比如说,我需要编写一个Urlcase类,并且可以从以下命令创建此类的实例java.net.URI:
object Url {
def apply(uri: URI): Url = Url(uri.getScheme, uri.getHost, uri.getRawPath)
}
case class Url(protocol: String, host: String, path: String) {
def protocol(value: String): Url = copy(protocol = value)
def host(value: String): Url = copy(host = value)
def path(value: String): Url = copy(path = value)
}
Run Code Online (Sandbox Code Playgroud)
一个URI实例可以返回null了getScheme,getHost和getRawPath.是否足以在apply(URI)方法中防止这些(require例如,使用语句)?从技术上说,为了完全安全的,它会是更好地保护protocol …
我一直在阅读Scala中的类型类,并认为我对它有很好的把握,直到我记得Java java.util.Comparator.
如果我理解正确,Ordering是类型类的原型示例.我可以在a Comparator和实例之间想到的唯一区别Ordering是比较器必然是显式的,而排序可以是,而且往往是隐含的.
是Comparator一个类型?我得到(错误的?)印象,Java实际上没有类型类.这是否意味着类型类需要能够隐式?我认为类型类的隐式转换主要是语法糖 - 实际上很棒,它"简单地"给编译器足够的提示 - 我错过了什么?
下面的代码示例显示了如何Comparator将排序操作添加到没有它的类型,而无需修改所述类型.
// Comparator used to retroactively fit the MyExample class with an ordering operation.
public static class MyExampleComparator implements Comparator<MyExample> {
public static final Comparator<MyExample> SINGLETON = new MyExampleComparator();
private MyExampleComparator() {}
public int compare(MyExample a, MyExample b) {
return a.value - b.value;
}
}
// Custom type, its only purpose is to show that Comparator can add an ordering operation …Run Code Online (Sandbox Code Playgroud) 我正在尝试Set在Haskell中实现一个简单的操作,并且如何为它包含的元素表达类约束.
该Set类型的类是相当简单:
class Set s where
empty :: s a
isEmpty :: s a -> Bool
insert :: s a -> a -> s a
contains :: s a -> a -> Bool
Run Code Online (Sandbox Code Playgroud)
a的简单实现Set是二叉搜索树:
data BinarySearchTree a = Node a (BinarySearchTree a) (BinarySearchTree a) | Leaf
Run Code Online (Sandbox Code Playgroud)
然而,当涉及到声明正确的类约束时,我有点卡住了:
Set至少需要能够决定两个元素是否相等 - 它的值需要有一个实例Eq.BinarySearchTree要求其元素具有实例Ord,因为每个节点需要在左侧具有较小的元素而在右侧具有较大的元素.第一个简单的解决方案是更新Set签名,要求a有一个实例Eq:
class Set s where
empty :: Eq a => s …Run Code Online (Sandbox Code Playgroud) 我正在研究CSV解析库(制表).它使用简单的类型类进行编码/解码:例如,编码是通过CellEncoder(编码单个单元格)和RowEncoder(编码整行)的实例完成的.
使用无形,我发现自动派生以下类型类实例非常简单:
RowEncoder[A]if A是一个案例类,其字段都有一个CellEncoder.RowEncoder[A]如果A是ADT,其替代品都有RowEncoder.CellEncoder[A]如果A是ADT,其替代品都有CellEncoder.事实是,最后一个在现实生活中几乎完全无用:ADT的替代品几乎总是案例类,而且我不能CellEncoder为具有多个字段的案例类派生.
然而,我希望能够做的是派生一个CellEncoder具有单个字段的案例类,其类型具有CellEncoder.这将涵盖,例如Either,scalaz's \/,cats' Xor......
这是我到目前为止:
implicit def caseClass1CellEncoder[A, H](implicit gen: Generic.Aux[A, H :: HNil], c: CellEncoder[H]): CellEncoder[A] =
CellEncoder((a: A) => gen.to(a) match {
case h :: t => c.encode(h)
})
Run Code Online (Sandbox Code Playgroud)
这明确使用时工作正常:
case class Bar(xs: String)
caseClass1CellEncoder[Bar, String]
res0: tabulate.CellEncoder[Bar] = tabulate.CellEncoder$$anon$2@7941904b
Run Code Online (Sandbox Code Playgroud)
然而,我不能隐含地工作,以下失败:
implicitly[CellEncoder[Bar]] …Run Code Online (Sandbox Code Playgroud) 我有一个函数,需要相同类型的可变数量的参数,这听起来像varargs的教科书用例:
def myFunc[A](as: A*) = ???
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是myFunc无法接受空参数列表.在运行时有一种简单的方法可以强制执行:
def myFunc[A](as: A*) = {
require(as.nonEmpty)
???
}
Run Code Online (Sandbox Code Playgroud)
问题在于它发生在运行时,而不是编译时.我希望编译器拒绝myFunc().
一种可能的解决方案是:
def myFunc[A](head: A, tail: A*) = ???
Run Code Online (Sandbox Code Playgroud)
这在myFunc使用内联参数调用时有效,但我希望我的库的用户能够传入一个List[A],这种语法非常笨拙.
我可以尝试两者兼得:
def myFunc[A](head: A, tail: A*) = myFunc(head +: tail)
def myFunc[A](as: A*) = ???
Run Code Online (Sandbox Code Playgroud)
但是我们回到了我们开始的地方:现在有一种myFunc使用空参数列表调用的方法.
我知道scalaz NonEmptyList,但是尽可能地,我想继续使用stlib类型.
有没有办法通过标准库来实现我的想法,或者我是否需要接受一些运行时错误处理,以获得真正感觉编译器应该能够处理的内容?
Scala类在其伴随对象中拥有apply和使用unapply方法是很常见的.
行为unapply是明确的:如果其参数是或可以转换为类的有效实例,则返回Some它的一个.否则,返回None.
举一个具体的例子,让我们想象一个Url案例类:
object Url {
def apply(str: String): Url = ???
def unapply(str: String): Option[Url] = ???
}
case class Url(protocol: String, host: String, path: String)
Run Code Online (Sandbox Code Playgroud)
如果str是有效的URL,则unapply返回a Some[Url],否则返回None.
apply但是对我来说有点不太清楚:它应该如何应对str不成为有效的URL?
来自Java世界,我的第一直觉是抛出一个IllegalArgumentException,这将允许我们实现伴侣对象:
object Url {
def apply(str: String): Url = ... // some function that parses a URI and throws if it fails.
def unapply(str: String): Option[Url] …Run Code Online (Sandbox Code Playgroud) 我在 scalacheck 1.13.3 中遇到了一个奇怪的问题:任意实例A => java.util.Date根据调用时间生成不同的值。
这是一个具体的、可重现的示例:
import org.scalatest.FunSuite
import org.scalatest.prop.GeneratorDrivenPropertyChecks
import java.util.Date
import org.scalacheck._
class Repr extends FunSuite with GeneratorDrivenPropertyChecks {
implicit val cogenDate: Cogen[Date] = Cogen(_.getTime)
test("reproduce") {
forAll { (s: String, g: String => Date) =>
val d1 = g(s)
Thread.sleep(100)
val d2 = g(s)
assert(d1 === d2)
}
}
}
Run Code Online (Sandbox Code Playgroud)
这失败了。d1打印和的实际值d2显示日期确实不同,差异在 100 到 103 毫秒之间。
我猜问题出在我的Cogen实例上,但我必须承认我不明白为什么。
我的一个项目使用scala功能混合,看起来不能很好地混合在一起:
我遇到的问题是类型类实例派生失败,如果:
Lazy这是我可以编写的用于重现问题的最小代码量:
import shapeless._
trait Show[A] {
def show(a: A): String
}
object Show {
def from[A](f: A => String): Show[A] = new Show[A] {
override def show(a: A) = f(a)
}
implicit val intShow: Show[Int] = Show.from(_.toString)
implicit def singletonShow[A](implicit
sa: Show[A]
): Show[A :: HNil] = Show.from {
case (a :: HNil) => sa.show(a)
}
implicit def singletonCaseClassShow[A, H <: HList](implicit
gen: Generic.Aux[A, H],
sh: Lazy[Show[H]]
): Show[A] = Show.from …Run Code Online (Sandbox Code Playgroud) 我正在使用Unfiltered 0.6.8(使用Jetty连接器)并遇到了一个奇怪的行为:路径段不是URL解码的.
以下代码是我的最小测试用例:
import unfiltered.request._
import unfiltered.response._
object Test extends App with unfiltered.filter.Plan {
def intent = {
case reg @ Path(Seg(test :: Nil)) =>
println(test)
ResponseString(test)
}
unfiltered.jetty.Http.local(8080).filter(Test).run()
}
Run Code Online (Sandbox Code Playgroud)
查询http://localhost:8080/some_string产生预期结果:some_string,在客户端和服务器端.
另一方面,客户端和服务器上的http://localhost:8080/some%20string产量some%20string,而不是some string我期待的.
解决这个问题很简单(java.net.URLDecoder#decode(String, String)),但我想知道是否:
作为旁注,unfiltered标签不存在,我没有足够的声誉来创建它,这就是我违约的原因scala.