开发者

scheme cond in scala language

开发者 https://www.devze.com 2023-01-23 23:39 出处:网络
Does scala have an equivalent 开发者_JAVA百科to scheme\'s cond?I guess you\'re looking for match (or just simply if/else if/else).case class Paired(x: Int, y: Int)

Does scala have an equivalent 开发者_JAVA百科to scheme's cond?


I guess you're looking for match (or just simply if/else if/else).


case class Paired(x: Int, y: Int)

def foo(x: Any) = x match {
  case string : String => println("Got a string")
  case num : Int if num < 100 => println("Number less than 100")
  case Paired(x,y) => println("Got x and y: " + x + ", " + y)
  case unknown => println("??: " + unknown)
}

The first two case statements show type based pattern matching. The third shows the use of an Extractor to break data down into constituent parts and to assign those parts to variables. The third shows a variable pattern match which will match anything. Not shown is the _ case:

case _ => println("what")

Which like the variable pattern match, matches anything, but does not bind the matched object to a variable.

The case class at the top is Scala shorthand for creating an extractor as well as the class itself.


Of course, neither match nor if does exactly the same thing as cond. One possibility is to do like this:

object Cond {
  def apply(clauses: Iterable[(()=>Boolean, ()=>Any)]): Any = {
    clauses find (_._1()) map (_._2()) getOrElse ()
  }
}

This object accepts something Iterable where each item is a pair of a function returning Boolean and a function returning Any. It tries to find an item whose first function returns true, stops looking if it finds one, calls the second function on a found item and returns the result of that function (or () if none was found).

Examples:

val clauses = Seq(
  ({()=>false}, {()=>println("foo")}),
  ({()=>true}, {()=>println("bar")})
)
Cond(clauses)

def checkYear(year: Int) = {
  Cond(Seq(
    ({()=>year % 400 == 0}, {()=>42}),
    ({()=>true}, {()=>{c:Char => (c.toString * 3)}})
  ))
}

ETA: Yes, I know it is ugly, but it works.


The most straightforward translation is to use pattern guards, although it requires some boilerplate. Pattern guards only work in a case pattern, and case only works in a match (unless we're writing a PartialFunction).

We can satisfy these conditions by matching a unit value against trivial cases:

;; Scheme
(cond
  (foo bar)
  (baz quux)
  (t   mydefault))

// Scala
() match {
  case _ if foo => bar
  case _ if baz => quux
  case _        => mydefault
}
0

精彩评论

暂无评论...
验证码 换一张
取 消