代码之家  ›  专栏  ›  技术社区  ›  ziggystar

Scala中映射及其条目的问题

  •  1
  • ziggystar  · 技术社区  · 16 年前

    def breadthFirstHelper( found: Map[AIS_State,(Option[AIS_State], Int)] ): List[AIS_State] = {
      val extension =
       for( 
         (s, v) <- found; 
         next <- this.expand(s) if (! (found contains next) )
       ) yield (next -> (Some(s), 0))
    
      if ( extension.exists( (s -> (p,c)) => this.isGoal( s ) ) )
        List(this.getStart)
      else
        breadthFirstHelper( found ++ extension )
    }
    

    。我尝试在上使用exists方法来完成此操作

    1. 在这样一个不可变的Map上做递归工作是个好主意吗?这种功能风格好吗?

    2 回复  |  直到 16 年前
        1
  •  1
  •   Daniel C. Sobral    16 年前

    使用模式匹配时(例如,针对 Tuple2 )在函数中,您需要使用大括号 {} case

    if (extension.exists { case (s,_) => isGoal(s) } )
    

    _ case xyz PartialFunction 其又从 Function1 exists 方法。

    至于风格,我不是函数式编程专家,但这似乎会被编译成迭代形式(即它的尾部递归)

    备注 -> 是一种方法 Any (通过隐式转换)创建 -确实如此 不是案例类 喜欢 :: ! 案例 模式匹配语句。这是因为:

    val l: List[String] = Nil
    l match {
      case x :: xs =>
    }
    

    case ::(x, xs) =>
    

    a ! b !(a, b) -> ...

    :正如Daniel在下面所说,在任何情况下都不能在函数定义中使用模式匹配;因此,尽管上述 部分函数 有效,以下函数无效:

    (x :: xs) =>
    
        2
  •  4
  •   oxbow_lakes    16 年前

    无论Oxbow Lakes怎么想,这对我来说都有点复杂。

    首先,我想澄清一点:理解没有中断条件。它们不是像C(或Java)那样的循环 for

    什么 if 在一个理解手段是一个警卫。例如,假设我这样做:

    for {i <- 1 to 10
         j <- 1 to 10
         if i != j
    } yield (i, j)
    

    跳跃 该条件为假的迭代,并继续进行真的迭代。下面是另一个例子:

    for {i <- 1 to 10
         j <- 1 to 10
         if i % 2 != 0
    } yield (i, j)
    

    你说你没有副作用,所以我可以跳过一整章关于副作用的内容,并注意理解。另一方面,阅读我最近在 Strict Ranges

    所以…放弃休息条件。它们可以工作,但它们不起作用。尝试以更实用的方式重新表述问题,对中断条件的需求将被其他条件所取代。

    (s -> (p,c) => -> 但是,唉,甚至 (a :: b) => =>

    if ( extension.exists( t => val (s, (p,c)) = t; this.isGoal( s ) ) )
    

    -> , 这之所以有效,是因为 a -> b (a, b) Tuple2(a, b) p c

    if ( extension.exists( t => val (s, _) = t; this.isGoal( s ) ) )
    

    final

    final def breadthFirstHelper
    

    def breadthFirstHelper(...) {
      def myRecursiveBreadthFirstHelper(...) { ... }
      myRecursiveBreadthFirstHelper(...)
    }
    

    在Scala 2.8上有一个名为 @TailRec 可以 如果稍有变化,则使尾部递归,如上所述。

    编辑

    case exists 取,一个功能。但是,必须小心确保始终有匹配,否则会出现异常。例如:

    scala> List(1, 'c') exists { case _: Int => true }
    res0: Boolean = true
    
    scala> List(1, 'c') exists { case _: String => true }
    scala.MatchError: 1
            at $anonfun$1.apply(<console>:5)
            ... (stack trace elided)    
    
    scala> List(1, 'c') exists { case _: String => true; case _ => false }
    res3: Boolean = false
    
    scala> ({ case _: Int => true } : PartialFunction[AnyRef,Boolean])
    res5: PartialFunction[AnyRef,Boolean] = <function1>
    
    scala> ({ case _: Int => true } : Function1[Int, Boolean])
    res6: (Int) => Boolean = <function1>
    

    案例 语句,它们确实使用模式匹配。当我说这不可能时,我指的是语法 x => s