Idiomatic way of treating Option[Boolean] - scala

In my Scala program, I am receiving some JSON.
One of the fields is an optional Boolean. If the field is missing, or if its value is false, I would like to return None. If its value is true, I would like to return Some(true).
SInce this is equivalent to converting Some(false) into None, I have defined the following function:
def boolmap(ob: Option[Boolean]) = if(ob == Some(false)) None else ob
It works, but it doesn't seem to be very idiomatic. Is there anything more elegant?

This is ob.filter(identity). I'm not sure whether that's clearer, but it's shorter.

I agree with others that you might as well just return true or false since you aren't differentiating between the attribute not being there at all, being null or being false.
If you just returned Boolean you could do it this way:
scala> Some(true) exists { _ == true }
res0: true
scala> Some(false) exists { _ == true }
res1: Boolean = false
scala> None exists { _ == true }
res2: Boolean = false
If you insist on returning Option[Boolean] a pattern match would be more idiomatic:
ob match {
case Some(true) => Some(true)
case _ => None
}
You could also use collect but in this case it would look IMO weird:
obj collect { case true => true }

Related

Effective way to case match a tuples with boolean values in scala

I want to case match tuples which contain boolean values.
Is there an effective way to match the results as case match on boolean looksexhautive
val ABC= "abc"
val DEF = "def"
private def istest1 = true
private def istest2 = true
private def istest3 = true
(istest1, istest2, istest3) match {
case (true, true, true)=>ABC
case (false, true, true) =>DEF
case (false , false , true)=> //print something else
//other cases
}
You need to have a statement for each of the possible outcomes, and using match seems to be the most compact and readable way to do it.
One possible improvement is to use _ for "don't care" values:
(istest1, istest2, istest3) match {
case (true, true, true) => ABC
case (_, true, true) => DEF
case (false, _, true) => //print something
case _ => //other cases
}
There may be performance issues with different versions of these tests, but it is best to pick the one that makes the most sense. Aim for readability and maintainability above perceived performance.
Your approach seems fine, but given all of your values are boolean you could use some stable identifiers to name them and make the code a bit more readable
val ABC = "abc"
val DEF = "def"
def isTest1 = true
def isTest2 = true
def isTest3 = true
val PassedTest1 = true
val PassedTest2 = true
val PassedTest3 = true
val NotPassedTest1 = false
val NotPassedTest2 = false
(isTest1, isTest2, isTest3) match {
case (PassedTest1, PassedTest2, PassedTest3) => ABC
case (NotPassedTest1, _, PassedTest3) => DEF
case (NotPassedTest1, NotPassedTest2, PassedTest3) => //print something
case _ => ???
}
Also as #Tim mentioned, you can use _ to match any value inside the tuple, or to match any tuple as the last case so you don't have to be exaustive
I would even go one step further to Brunos solution:
sealed trait PassedOrNot {
final val Passed = true
final val NotPassed = false
}
case object Test1 extends PassedOrNot
case object Test2 extends PassedOrNot
case object Test3 extends PassedOrNot
def isTest1 = true
def isTest2 = true
def isTest3 = true
(isTest1, isTest2, isTest3) match {
// #formatter:off
case (Test1.Passed , Test2.Passed, Test3.NotPassed) => ???
case (Test1.NotPassed, _ , Test3.NotPassed) => ???
case _ => ???
// #formatter:on
}

Scala matching high order function return value

Hello im trying to use case match with a high order function. if function return true do things same for false. Thank you.
def funk(ls:List[Int],f:Int=>Boolean):List[Int]=
{
f match
{
case true => do something
case false => do somethingelse
}
}
Looks like a good place to apply "andThen" for partial function:
Here is possibly what you need:
def funk(ls: List[Int], f: Int => Boolean): List[Int] = {
val z = f.andThen(r => r match {
case true => List(1, 2) // ..something
case false => List(3, 4) // somethingElse
})
// function application
z(5)
}
Just dig a bit around PartialFunction's:
http://www.scala-lang.org/api/current/scala/PartialFunction.html
you have to execute the function and pass the return value to the match case as
def funk(ls:List[Int],f:Int=>Boolean):List[Int]=
{
f(some integer value) match
{
case true => return a list of integers
case false => return a list of integers
}
}
for example
def funk(ls:List[Int],f:Int=>Boolean):List[Int]=
{
f(ls(0)) match
{
case true => List(1,2)
case false => List(4,3)
}
}

Find an element in a list in Scala

I'm trying to write a function myfoo which, taken an Int and a list of ints, verifies if the int element is in the list or not. It should return "true" if the int is in the list, false otherwise.
I've written this function, but when I compile it it returns this error:
error: type mismatch;
found : Unit
required: Boolean
breakable { for (i <-l) {
^
one error found*
This is my program:
import scala.util.control.Breaks._
object findEl extends App{
def myfoo (x:Int,l:List[Int]):Boolean={
breakable { for (i <-l) {
i match {
case a if (a==x) => true
case _ => false
break
}
}
}
}
println(myfoo(1,List(1,2,3,4))) //should print "true"
}
How can I solve it? :)
This is how breakable is implemented
def breakable(op: => Unit) {
try {
op
} catch {
case ex: BreakControl =>
if (ex ne breakException) throw ex
}
}
Breakable returns Unit finally. So thats why compiler is complaining.
Here is one way to fix this. Notice I am using var
import scala.util.control.Breaks._
object findEl extends App {
def myfoo(x: Int, l: List[Int]): Boolean = {
var res: Boolean = false
breakable {
for (i <- l) {
i match {
case a if a == x => res = true
break
case _ => ()
}
}
}
res
}
println(myfoo(1, List(1, 2, 3, 4))) //should print "true"
}
Functional way (better way) of implementing the same
def myFoo(num: Int, list: List[Int]): Boolean = list match {
case Nil => false
case `num` :: xs => true
case _ => myFoo(num, list.tail)
}
Below code is same but does not use back ticks
def myFoo(num: Int, list: List[Int]): Boolean = list match {
case Nil => false
case x :: xs if x == num => true
case _ => myFoo(num, list.tail)
}
Scala REPL
scala> def myFoo(num: Int, list: List[Int]): Boolean = list match {
| case Nil => false
| case `num` :: xs => true
| case _ => myFoo(num, list.tail)
| }
myFoo: (num: Int, list: List[Int])Boolean
scala> myFoo(1, List(2, 1, 2))
res0: Boolean = true
Using breakable is not functional practice
Halting the execution of the program using an exception is not functional. Functional programming advocates communicating through interpretation of types. Internally breakable halts the control flow by throwing exception.
Above second way is the way to solve the problem functionally.
you can use this trick instead
def function myFoo(x:Int, xList:List[Int]) = xList.contains(x)
println(myFoo(1, List(1,2,3,4,5,6)))

Idiomatically evaluate true if Option contains specific value

I want to write a method that returns true if an Option[Int] contains a specific value and false otherwise. What is the idiomatic way of doing this?
var trueIf5(intOption: Option[Int]): Boolean {
intOption match {
case Some(i) => i == 5
case None => false
}
}
This above solution clearly works, but the Scala docs label this approach as less-idiomatic.
Is there some way I can do the same thing using map, filter, or something else?
I got this far, but it only changes the problem to "Return true if Option contains true", which is effectively the same as "Return true if Option contains 5".
var trueIf5(intOption: Option[Int]): Boolean {
intOption.map(i => i == 5).???
}
Since you're testing whether it contains a value:
scala> Some(42) contains 42
res0: Boolean = true
Don't neglect your -Xlint:
scala> Option(42).contains("")
res0: Boolean = false
scala> :replay -Xlint
Replaying: Option(42).contains("")
<console>:12: warning: a type was inferred to be `Any`; this may indicate a programming error.
Option(42).contains("")
^
res0: Boolean = false
Those built-in warnings aren't as effective with universal equality:
scala> Option(42).exists("" == _) // no warning
res1: Boolean = false
intOption.exists(_ == 5)
The doc
Why has no one suggested:
intOption == Some(5)

Scala, represent pattern of boolean tuple into something else

This is a cellular automata rule (input Boolean == Left, Center, Right Cell) and output Boolean. What is a better way to represent this in Scala?
trait Rule {
def ruleId() : Int
def rule(inputState:(Boolean, Boolean, Boolean)) : Boolean
override def toString : String = "Rule:" + ruleId
}
class Rule90 extends Rule {
def ruleId() = 90
def rule(inputState:(Boolean, Boolean, Boolean)) : Boolean = {
// Verbose version, show all 8 states
inputState match {
case (true, true, true) => false
case (true, false, true) => false
case (false, true, false) => false
case (false, false, false) => false
case _ => true
}
}
}
One observation... In typical use, you're going to find that the sliding method is the easiest way to feed data into your automata. It works something like this:
scala> val input = Seq(1,2,3,4,5,6,7,8,9)
input: Seq[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> input.sliding(3).toList
res4: List[Seq[Int]] =List(
List(1, 2, 3),
List(2, 3, 4),
...
List(6, 7, 8),
List(7, 8, 9))
To ensure that the number of sequences output by sliding is equal to the number of input elements, you need to pad the input sequence on either side:
scala> (0 +: input :+ 0).sliding(3).toList
res9: List[Seq[Int]] = List(
List(0, 1, 2),
List(1, 2, 3),
...
List(7, 8, 9),
List(8, 9, 0))
Enough of the theory then, back to the code!
For your example (and because I understand something of the underlying problem) I'm padding the sequence with false values here.
Because sliding will output sequences and not tuples, I created the seqYieldsTrue helper method to handle the translation. I also renamed rule to apply, so that your class can be directly used as a function:
trait Rule {
def ruleId: Int //abstract
def yieldsTrue(input: (Boolean,Boolean,Boolean)): Boolean //abstract
override def toString: String = "Rule:" + ruleId
private def seqYieldsTrue(input: Seq[Boolean]) = {
assert(input.size == 3)
input match {
case Seq(a,b,c) => yieldsTrue((a,b,c))
case _ => error("invalid input size")
}
}
def apply(input: Seq[Boolean]) =
(false +: input :+ false).sliding(3) map { seqYieldsTrue }
}
class Rule90 extends Rule {
val ruleId = 90
val falsehoods = Seq(
(true, true, true),
(true, false, true),
(false, true, false),
(false, false, false)
)
def yieldsTrue(input: (Boolean,Boolean,Boolean)) = !falsehoods.contains(input)
}
Then again, I did say I understood the underlying problem! So lets just do away with all these tedious manual rule definitions, and let the compiler generate the lot for us :)
If you don't mind some bit-twiddling...
class WolframAutomata(val ruleId: Int) extends Rule {
def pow2(x: Int) = math.pow(2,x).toInt
def isBitSet(x: Int, bit: Int) = (x & pow2(bit)) > 0
// 8 possible input patterns corresponding to
// different combinations of 3 input bits
val inputs = (0 to 7) map { id =>
Tuple3(
isBitSet(id, 2),
isBitSet(id, 1),
isBitSet(id, 0)
) -> id
} toMap
//each of the 8 input rules corresponds to one bit in the ruleId
val outputs = inputs mapValues { isBitSet(ruleId, _) }
def yieldsTrue(input: (Boolean,Boolean,Boolean)) = outputs(input)
}
(the rule for generating automata from IDs taken from here: http://www.wolframscience.com/nksonline/page-53#previous)
Working like this, you can also roll the logic back up into the Rule trait, as there's little need for a separate abstract trait if there'll only ever be one subclass. You could also safely do away with yieldsTrue in this case and just work directly with the output val. I'll leave that as an exercise to the reader...
Putting it all together (useless REPL output lines removed):
scala> val r90 = new WolframAutomata(90)
r90: WolframAutomata = Rule:90
scala> def destringify(s:String) = s map { case 'X' => true; case _ => false } toSeq
scala> val input = destringify(".......X.......")
scala> val output = Iterator.iterate(input)(r90.apply(_).toSeq) toSeq
scala> def stringify(xs: Seq[Boolean]) = xs map {case true => "X"; case _ => "."} mkString
//can you see what it is yet?
scala> val sierpinski = output.take(10).map(stringify).mkString("\n")
sierpinski: String =
.......X.......
......X.X......
.....X...X.....
....X.X.X.X....
...X.......X...
..X.X.....X.X..
.X...X...X...X.
X.X.X.X.X.X.X.X
...............
...............
Please forgive all the toSeq calls, they're mostly to force evaluation so that you can see some actual output on the REPL, and not just non-empty iterator
Instead of
inputState match {
case (true, true, true) => false
case (true, false, true) => false
case (false, true, false) => false
case (false, false, false) => false
case _ => true
}
you could say
inputState match {
case (true, _, true) | (false, _, false) => false
case _ => true
}
or, simply but maybe not as clearly (depending on purpose/context)
def rule(inputState:(Boolean, Boolean, Boolean)) = inputState._1 != inputState._3
The other answers focused on how to optimize the pattern matching to make it shorter. However, I think that Rule90 might be only an example here. Maybe your question is not how to optimize the pattern matching of rule 90, but if there is a more appropriate way to define the rule type with Scala constructs. Here is my take on that.
First, I wouldn't recommend making subclasses for different rules. You should have one single Rule class, and all the concrete rules would be instances of it. Here would be my definition of the Rule class:
case class Rule(val id:Int, f:PartialFunction[(Boolean,Boolean,Boolean),Boolean])
extends (((Boolean,Boolean,Boolean))=>Boolean) {
def apply(state:(Boolean,Boolean,Boolean)) = f(state)
}
Now, the Rule class is also a proper Scala function. You can instantiate it quite easily, like this:
val rule90 = Rule(90, {
case (true, true, true) => false
case (true, false, true) => false
case (false, true, false) => false
case (false, false, false) => false
case _ => true
})
That's why I chose f to be a PartialFunction, so we can use the Scala syntax for defining partial functions without any overhead, just like this. The disadvantage is that the compiler won't complain in case the match is not exhaustive. You need to make up your mind which is more important to you: code brevity or exhaustive error checking.
If the latter is the case, you can change f to be a Function, by declaring its type as ((Boolean,Boolean,Boolean))=>Boolean. In that case, you would need to declare a specific rule by passing f as a closure to the constructor.
You can apply the Rule function very easily:
val state = (true, false, true)
val newState = rule90(state) // should be false
Also, there are more tricks you can do. Let's say you have all your rules inside a list:
val ruleList = List(rule01, rule02, rule03 /* .... */)
Then, you can for example make a mapping from rule id to rule instance like this:
val rules = ruleList.map(r=>(r.id, r)).toMap
And you could access and use a rule like that:
val state = (true, false, true)
val newState = rules(90)(state)
Or, in order to get all of the next states for all rules:
val state = (true, false, true)
val newStates = rules mapValues _(state)
And access one of the results like this:
val newState_90 = newStates(90)
Pretty cool. However, you can do most of this also with your original Rule definition. I just wanted to play with the idea a little, because I love cellular automata.
You can use extractors to put meaning on the input state values
object EqualLeftAndRight {
def unapply(inputState:(Boolean, Boolean, Boolean)) = inputState._1 == inputState._3
}
def rule(inputState:(Boolean, Boolean, Boolean)) : Boolean =
inputState match {
case EqualLeftAndRight() => true
case _ => false
}
Also, to extend on #Madoc's answer, since you pass a partial function, it doesn't need to cover all cases:
case class Rule(val id:Int)(f:PartialFunction[(Boolean,Boolean,Boolean),Boolean]) extends (((Boolean,Boolean,Boolean))=>Boolean) {
def apply(state:(Boolean,Boolean,Boolean)) = if (f.isDefinedAt(state)) f(state) else false
}
val rule90 = Rule(90) {
case EqualLeftAndRight() => true
}
One additional point, if your ruleIds are meant to be constants, then you can (and should) declare them as vals rather than null-arg defs. Like your defs, the vals defined can be abstract in the trait, and concrete in the class.
trait Rule {
val ruleId : Int
}
class Rule90 extends Rule {
val ruleId= 90
}
Simplified further...
Welcome to Scala version 2.8.0.final (Java HotSpot(TM) Client VM, Java 1.6.0_21).
Type in expressions to have them evaluated.
Type :help for more information.
scala> def rule(inputState:(Boolean, Boolean, Boolean)) = inputState._1 != inputState._3
rule: (inputState: (Boolean, Boolean, Boolean))Boolean
scala> rule((true, false, true))
res0: Boolean = false
scala> rule((true, false, false))
res1: Boolean = true
scala> rule((false, false, false))
res2: Boolean = false
scala> rule((false, true, false))
res3: Boolean = false
scala> rule((false, true, true))
res4: Boolean = true
Oops, sorry, I see #Debilski has this already.