开发者

Scala: concise way to express the following construct

I'll give some C-style "bracket" pseudo-code to show what I'd like to express in another way:

for (int i = 0; i < n; i++) {
    if (i == 3 || i == 5 || i == 982) {
        assertTrue( isCromulent(i) );      
    } else {
        assertFalse( isCromulent(i) );
    }
}

The for loop is not very important, that is not the point of my question: I'd like to know how I could rewrite what is inside the loop using Scala.

My goal is not to have the shortest code possible: it's because I'd like to understand what kind of manipulation can be done on method names (?) in Scala.

Can you do something like the following in Scala (following is still s开发者_如何学Goome kind of pseudo-code, not Scala code):

assert((i==3 || i==5 || i==982)?True:False)(isCromulent(i))

Or even something like this:

assertTrue( ((i==3 || i==5 || i==982) ?  : ! ) isCromulent(i) )

Basically I'd like to know if the result of the test (i==3 || i==5 || i==982) can be used to dispatch between two methods or to add a "not" before an expression.

I don't know if it makes sense so please be kind (look my profile) :)


While pelotom's solution is much better for this case, you can also do this (which is a bit closer to what you asked originally):

(if (i==3||i==5||i==982) assertTrue else assertFalse)(isCromulent(i))

Constructing names dynamically can be done via reflection, but this certainly won't be concise.


assertTrue(isCromulent(i) == (i==3||i==5||i==982))


Within the Scala type system, it isn't possible to dynamically create a method name based on a condition.

But it isn't at all necessary in this case.

val condition = i == 3 || i == 5 || i == 982
assertEquals(condition, isCromulent(i))


I hope nobody minds this response, which is an aside rather than a direct answer.

I found the question and the answers so far very interesting and spent a while looking for a pattern matching based alternative.

The following is an attempt to generalise on this (very specific) category of testing:

class MatchSet(s: Set[Int]) {def unapply(i: Int) = s.contains(i)}
object MatchSet {def apply(s: Int*) = new MatchSet(Set(s:_*))}


val cromulentSet = MatchSet(3, 5, 982)

0 until n foreach {
  case i @ cromulentSet() => assertTrue(isCromulent(i))
  case i                  => assertFalse(isCromulent(i))
}

The idea is to create ranges of values contained in MatchSet instances rather than use explicit matches.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜