- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有几个类都扩展了相同的特征,并且都共享应该改变它们状态的相互功能。但是我想知道是否有更好的方法来实现相同的功能。
例如:
trait Breed
case object Pincher extends Breed
case object Haski extends Breed
trait Foox{
def age: Int
def addToAge(i: Int): Foox
}
case class Dog(breed: Breed, age: Int) extends Foox
case class Person(name: String, age: Int) extends Foox
addToAge
将返回具有附加 int 的相同对象,
case class Dog(breed: Breed, age: Int) extends Foox{
def addToAge(i: Int) = copy(age = age + i)
}
case class Person(name: String, age: Int) extends Foox{
def addToAge(i:Int) = copy(age = age + i)
}
最佳答案
一种可能涵盖某些用例的可能解决方案是使用 Lens
es 来自 shapeless
图书馆:
import shapeless._
abstract class Foox[T](
implicit l: MkFieldLens.Aux[T, Witness.`'age`.T, Int]
) {
self: T =>
final private val ageLens = lens[T] >> 'age
def age: Int
def addToAge(i: Int): T = ageLens.modify(self)(_ + i)
}
case class Dog(breed: Breed, age: Int) extends Foox[Dog]
case class Person(name: String, age: Int) extends Foox[Person]
Lens
你需要一个隐含的
MkFieldLens
,所以更容易定义
Foox
作为
abstract class
而不是
trait
.否则,您必须在每个 child 中编写一些代码来提供隐式。
age: Int
在每个 child 身上。在构建实例时,您必须以某种方式提供年龄,例如
Dog(Pincher, 5)
,所以你必须有那个年龄的构造函数参数。
A lens is a first-class reference to a subpart of some data type. [...] Given a lens there are essentially three things you might want to do
- View the subpart
- Modify the whole by changing the subpart
- Combine this lens with another lens to look even deeper
The first and the second give rise to the idea that lenses are getters and setters like you might have on an object.
age
.
age
字段来自该示例:
final private val ageLens = lens[???] >> 'age
def age: Int
def addToAge(i: Int): ??? = ageLens.modify(self)(_ + i)
addToAge
的返回类型应该是什么是?它应该是调用此方法的子类的确切类型。这通常通过
F-bounded polymorphism 实现.所以我们有以下内容:
trait Foox[T] { self: T => // variation of F-bounded polymorphism
final private val ageLens = lens[T] >> 'age
def age: Int
def addToAge(i: Int): T = ageLens.modify(self)(_ + i)
}
T
在那里用作 child 的确切类型,并且每个类都扩展
Foox[T]
应将自己提供为
T
(因为自我类型声明
self: T =>
)。例如:
case class Dog(/* ... */) extends Foox[Dog]
lens[T] >> 'age
线工作。
>>
的签名方法来查看它需要什么功能:
def >>(k: Witness)(implicit mkLens: MkFieldLens[A, k.T]): Lens[S, mkLens.Elem]
'age
参数被隐式转换为 shapeless.Witness
. Witness
表示特定值的确切类型,即类型级别的值。两种不同的文字,例如Symbol
s 'age
和 'foo
, 有不同的见证人,因此可以区分它们的类型。Witness
有一定的值(value)。对于 'age
象征:Witness.`'age` // Witness object
Witness.`'age`.T // Specific type of the 'age symbol
>>
签名,我们需要有一个隐含的 MkFieldLens
可用,适用于类 T
(子 case class
)和字段 'age
:MkFieldLens[T, Witness.`'age`.T]
age
字段还应具有类型 Int
.可以用 Aux
pattern 来表达这个要求。常见于无形:MkFieldLens.Aux[T, Witness.`'age`.T, Int]
abstract class
而不是
trait
.
关于scala - 改变类状态的惯用方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37765846/
我对 Clojure 和函数式编程有了大约一周的了解——我的所有背景都是 OOP。我想利用 Clojure 备受争议的易读性和固有逻辑,但现在我不知道我是否成功地做到了这一点,只是没有完全理解它,或者
场景: val col: IndexedSeq[Array[Char]] = for (i = 0 && arr(last.y)(west) == '.') { arr(last.y)(w
我正面临 AngularJS、服务和范围的“问题”。 这不是一个真正的问题(我找到了几种使其工作的方法),但我想知道我是否在做正确的事情,或者我正在做的事情是否会导致将来出现问题 我有一个保存一些全局
进行以下数据结构转换的“Rubyist”方法是什么: 我有 incoming = [ {:date => 20090501, :width => 2}, {:
如何在 go 中编写返回集合最小值的函数?我不只是在寻找解决方案(我知道我可以在遍历第一个元素时只初始化最小值,然后设置一个我初始化最小值的 bool 变量),而是一个惯用的解决方案。由于 go 没有
好的,我知道我应该对我的特定应用程序进行基准测试,等等,但是: -Xmx 的默认 JVM 设置、默认垃圾收集器等,对于大多数典型的 Java 程序来说是合理的默认设置,并且可能不适合惯用的 Scala
既然 shared_ptr 在 tr1 中,你认为 std::auto_ptr 的使用会发生什么?它们都有不同的用例,但 auto_ptr 的所有用例也都可以用 shared_ptr 解决。你会放弃
这个问题在这里已经有了答案: What are the differences between type() and isinstance()? (8 个回答) 关闭 9 年前。 我需要知道 Pyth
在指定和创建数字函数时,是否有关于何时返回 null 以及何时返回 NaN 的任何 C# 惯用准则,当两者似乎都是有效输出时。 导致这个问题的具体例子是我正在为 Enumerable 集合创建一个百分
这个问题在这里已经有了答案: Retrieving the top 100 numbers from one hundred million of numbers [duplicate] (12 个
我可以通过反射检索方法,以某种方式将其与目标对象结合起来,并将其作为看起来像 Scala 中的函数的东西返回(即您可以使用括号调用它)吗?参数列表是可变的。它不一定是“一流”函数(我已经更新了问题),
我是一名优秀的程序员,十分优秀!