- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个多态函数,可以将列表转换为集合:
import shapeless.PolyDefns.~>
import shapeless._
val lists = List(1,2) :: List("A", "B") :: List(1.1, 2.2) :: HNil
object sss extends (List ~> Set) {
def apply[T](l:List[T]):Set[T] = {
l.toSet
}
}
lists.map(sss) // I want: Set(1,2) :: Set("A", "B") :: Set(1.1, 2.2) :: HNil
但是如果我想改变这个函数的行为怎么办 - 我现在想添加一个额外的参数来指定输入列表中的哪个项目应该放入集合中。这是一个不正确的语法 - 你能告诉我正确的方法吗?
object sss extends (List ~> Set) { // Compiler says no!
def apply[T](i:Int)(l:List[T]):Set[T] = {
l.slice(i,i+1).toSet
}
}
我认为这是失败的,因为额外的参数使它不再符合 List ~> Set 的签名,那么我该如何克服这个问题?
最佳答案
参数化 Poly
有几个解决方法,其中一个在另一个答案中提到,尽管那里的确切实现不起作用。相反,您需要这样做:
import shapeless._, shapeless.poly.~>
val lists = List(1, 2) :: List("A", "B") :: List(1.1, 2.2) :: HNil
class sss(i: Int) extends (List ~> Set) {
def apply[T](l: List[T]): Set[T] = l.slice(i, i+1).toSet
}
object sss1 extends sss(1)
lists.map(sss1)
...sss1
的事实被定义为编译最后一行所必需的对象(不是 val
)。
这种方法可以编译,但不可能在很多上下文中使用它——例如你不能定义你的 sss1
(或其他)方法中的对象,其中 hlist 的类型是通用的。
这是我以前使用过的稍微困惑但更灵活的解决方法:
import shapeless._
val lists = List(1, 2) :: List("A", "B") :: List(1.1, 2.2) :: HNil
object sss extends Poly2 {
implicit def withI[T]: Case.Aux[List[T], Int, Set[T]] =
at((l, i) => l.slice(i, i + 1).toSet)
}
lists.zipWith(lists.mapConst(1))(sss)
// Set(2) :: Set(B) :: Set(2.2) :: HNil
现在您实际上可以编写一个采用通用 L <: HList
的方法和切片参数 i
—你只需要几个隐式参数来支持 mapConst
和 zipWith
应用程序。
不过,这两种方法都不是很优雅,我个人倾向于避免使用 Poly
大多数时候 — 定义自定义类型类几乎会更简洁,并且在许多情况下是必需的。
关于scala - 将额外参数传递给多态函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39628068/
我来自 Asp.Net 世界,试图理解 Angular State 的含义。 什么是 Angular 状态?它类似于Asp.Net中的ascx组件吗?是子页面吗?它类似于工作流程状态吗? 我听到很多人
我一直在寻找 3 态拨动开关,但运气不佳。 基本上我需要一个具有以下状态的开关: |开 |不适用 |关 | slider 默认从中间开始,一旦用户向左或向右滑动,就无法回到N/A(未回答)状态。 有人
我是一名优秀的程序员,十分优秀!