这是我的问题:我有一个序列S(非空但可能不是不同)设置s_i,并且对于每个s_i需要知道S(i≠j)中有多少个集合s_j是s_i的子集.
我还需要增量性能:一旦我完成所有计数,我可以用s_i的某个子集替换一组s_i并逐步更新计数.
使用纯功能代码执行所有这些将是一个巨大的优势(我在Scala中的代码).
由于set包含是一个部分排序,我认为解决我的问题的最好方法是构建一个DAG,它表示集合的Hasse图,边表示包含,并将一个整数值连接到表示大小的每个节点节点下方的子d加1.但是,我已经被困了好几天试图开发从部分排序构建Hasse图的算法(让我们不谈增量!),即使我认为它会是一些标准本科教材.
这是我的数据结构:
case class HNode[A] (
val v: A,
val child: List[HNode[A]]) {
val rank = 1 + child.map(_.rank).sum
}
Run Code Online (Sandbox Code Playgroud)
我的DAG由根列表和一些部分排序定义:
class Hasse[A](val po: PartialOrdering[A], val roots: List[HNode[A]]) {
def +(v: A): Hasse[A] = new Hasse[A](po, add(v, roots))
private def collect(v: A, roots: List[HNode[A]], collected: List[HNode[A]]): List[HNode[A]] =
if (roots == Nil) collected
else {
val (subsets, remaining) = roots.partition(r => po.lteq(r.v, v))
collect(v, remaining.map(_.child).flatten, subsets.filter(r => !collected.exists(c => po.lteq(r.v, c.v))) ::: collected)
}
}
Run Code Online (Sandbox Code Playgroud)
我很困在这里.我最后向DAG添加了一个新值v:
functional-programming scala graph-theory partial-ordering directed-acyclic-graphs
让我们重用Daily scala中的示例:
type PF = PartialFunction[Int,Int]
val pf1 : PF = {case 1 => 2}
val pf2 : PF = {case 2 => 3}
Run Code Online (Sandbox Code Playgroud)
让我们补充一下:
val pf3 : PF = {case 3 => 4}
Run Code Online (Sandbox Code Playgroud)
然后按预期工作:
pf1 andThen pf2 isDefinedAt(x)
Run Code Online (Sandbox Code Playgroud)
返回trueiff x == 1(实际上,pf2根本不需要是PartialFunction)
但是,我预计:
pf1 andThen pf3 isDefinedAt(x)
Run Code Online (Sandbox Code Playgroud)
将返回false所有x(即,iff pf1已定义,检查pf3),但它不会,只验证pf1.
最后,pf1 andThen pf3 lift(x)总是会导致MatchError.我宁愿得到None ......我可以通过解除每个函数来获得这种行为,pf1.lift(x).flatMap(pf3.lift)但是有没有更简单的方法使用纯PartialFunction API?(并且不单独提升每个部分功能?)
这可能是之前提出的问题,但我有这个问题:
trait Container[+A] {
def a: A
def methodWithSideEffect() = {
// perform some side effecting work
this
}
}
class IntContainer(val a: Int) extends Container[Int]
Run Code Online (Sandbox Code Playgroud)
如何已在methodWithSideEffect中IntContainer返回IntContainer,而不是一个Container[Int]?我还想不要在Container特征中添加任何参数,至少从API用户的角度来看.请注意,我确实使用隐式进行了解决方法:
implicit class MyContainer[A <: Container[_]](c: A) {
def methodWithSideEffect(): A = {
// perform work
c
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我确信有一些方法可以更优雅地完成这项工作.
我想使用Scala Parser Combinators为某些定义的语言实现解析器.但是,编译该语言的软件并未实现所有语言的功能,因此如果使用这些功能,我希望失败.我试着在下面打造一个小例子:
object TestFail extends JavaTokenParsers {
def test: Parser[String] =
"hello" ~ "world" ^^ { case _ => ??? } |
"hello" ~ ident ^^ { case "hello" ~ id => s"hi, $id" }
}
Run Code Online (Sandbox Code Playgroud)
即,解析器成功"hello"+某个标识符,但如果标识符是"world"则失败.我看到Parsers类中存在fail()和err()解析器,但我无法弄清楚如何使用它们,因为它们返回Parser [Nothing]而不是String.该文档似乎不包括此用例...
我是Scala和高级编程语言的新手.我尝试解决以下问题.
我有:
val s: Seq[SomeMutableType[_]]
Run Code Online (Sandbox Code Playgroud)
我假设序列中的所有元素都是相同的类型(但此时不知道哪一个).
我怎么称呼:
def proc[T](v0: SomeMutableType[T], v1: SomeMutableType[T]) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
喜欢的东西
proc(s(0), s(1))
Run Code Online (Sandbox Code Playgroud)
编译器抱怨:
- 类型不匹配; found:SomeMutableType [_ $ 351]其中type _ $ 351 required:SomeMutableType [Any]注意:_ $ 351 <:Any,但类SomeMutableType在类型T中是不变的.您可能希望将T定义为+ T.(SLS 4.5)
我想到了那个协变的东西,但我不相信它在我的情况下是有道理的.当我说s(0)和s(1)属于同一类型时,我只想让编译器相信我!我通常通过一些转换来做这个,但我不能在这里强制转换为SomeMutableType [T],因为T由于擦除而未知.当然,我无法改变proc的定义.
我有一个函数将 A 类型的值映射到一对 (Seq[B], Seq[C])。我想将该函数应用于 A 的序列,并返回一对展平的 Seq[B] 和 Seq[C]。这是代码片段:
val a: Seq[A]
val mapped: Seq[(Seq[B], Seq[C])] = a.map(f)
val (b, c) = mapped.unzip
val bc: (Seq[B], Seq[C]) = (b.flatten, c.flatten)
Run Code Online (Sandbox Code Playgroud)
解决方案是可以接受的,但是有没有更惯用的方法来做到这一点?我虽然关于 for-comprehensions 或 flatMaps,但我不知道如何将它们应用于这对。
我想在一些Iterable中找到一些符合某些给定类型的元素,并验证将该类型作为参数的谓词.
我使用命令式编程编写了这个方法,这似乎符合我的期望.有没有办法用更"scalaesque"的方式写这个?
def findMatch[T](it: Iterable[_], clazz: Class[T], pred: T => Boolean): Option[T] = {
val itr = it.iterator
var res: Option[T] = None
while (res.isEmpty && itr.hasNext) {
val e = itr.next()
if (clazz.isInstance(e) && pred(clazz.cast(e))) {
res = Some(clazz.cast(e))
}
}
res
}
Run Code Online (Sandbox Code Playgroud) 我对Scala很新,并且仍然对其复杂的类型系统感到困惑.
我尝试解决以下问题.我想设计属于可变双向链表(以及更复杂的数据结构,如堆)的成员的类.当然,我的目标是能够在恒定的时间内从数据结构中删除对象.
我设计了以下特征:
trait DLLMember {
var next: DLLMember = this
var prev: DLLMember = this
...
}
Run Code Online (Sandbox Code Playgroud)
使用一些其他方法从列表中添加和删除对象.
问题是,当我在实际上课时,说:
class IntInDL(val v: Int) extends DLLMember
Run Code Online (Sandbox Code Playgroud)
在解析我的列表时,IntInDL.next会返回一个DLLMember类型而不是IntInDL,我必须强制转换它来检索值:这不好...
有没有办法利用Scala的类型系统来保持我的工作类型安全?
现在我很困惑.我是Scala的新手,已经使用了几个星期,我想我已经熟悉了它,但我仍然坚持看似简单的以下情况.
我找不到与此Java声明等效的Scala:
public static <T extends Comparable<T>> List<T> myMethod(List<T> values) {
// ...
final List<T> sorted = new ArrayList<T>(values);
Collections.sort(sorted);
// ...
}
Run Code Online (Sandbox Code Playgroud)
我以为会有以下情况:
def myMethod[A >: Ordering[A]](values: Seq[A]): Seq[A] = {
// ...
val sorted = values.sorted
//
}
Run Code Online (Sandbox Code Playgroud)
但是,我收到以下错误:
错误:涉及类型A的非法循环引用
错误:类型scala.math.Ordering [A]的分散隐式扩展从对象Ordering中的方法Tuple9开始
我哪里错了?
这是我想要做的:
def parser = parser_a >> {
case a => val c = compute(a) ; parser_b(c)
} ^^ {
case a ~ b => (a, b)
}
Run Code Online (Sandbox Code Playgroud)
当然它不起作用,因为^^运算符后的函数只得到结果parser_b.我怎样才能保持结果parser_a?
这是我的问题:我有一大堆对象,我想要应用程序(我称之为"编译器"),如果某些谓词适用.为清楚起见,我想将谓词函数与过程分开; 但是在很多情况下,谓词可能非常复杂,并构建了我想在后一个过程函数中重用的信息.
我定义了一个编译器如下:
trait Compiler[A] {
def mtch(o: SourceObject): Option[A]
def proceed(o: SourceObject, data: A): Unit
}
Run Code Online (Sandbox Code Playgroud)
如何调用编译器:
val compilers: Seq[Compiler[_]]
val objects: Seq[SourceObject]
for (o <- objects; c <- compilers; data <- c.mtch(o)) {
c.proceed(o, data)
}
Run Code Online (Sandbox Code Playgroud)
也就是说,如果mtch函数返回Some(data),则proceed调用该方法,并data附加.但是,我无法编译它,因为我在管理编译器时不知道数据的类型.
此外,我有一些我实际上不需要任何数据的情况.在我目前的状态,我有匹配返回Some(null),这很臭.
scala ×11
covariance ×2
parsing ×2
graph-theory ×1
self-type ×1
type-safety ×1
types ×1
variance ×1