Scala's || and | operators - scala

I noticed something today. Scala has the usual OR ||, but also the |.
My first thought was that the | was a strict OR. So true | true, will evaluate to false.
But,
val x = true
x: Boolean = true
val y = true
y: Boolean = true
x || y
res4: Boolean = true
x | y
res5: Boolean = true
What is the | operator for? Is it just an alias?

As in Java, the single & and | operators do the same thing as their usual versions but without short-circuiting.
As an example, consider the expression true || isNice(). The method will never be called because true || x is always true and the compiler (and runtime) knows that. If you insist on all parts of a boolean expression to be evaluated, you have to use & or |.
Edit: For completeness, Scala also uses the | for alternative patterns in pattern matching. This is copied from the language reference:
8.1.11 Pattern Alternatives
Syntax:
Pattern ::= Pattern1 { ‘|’ Pattern1 }
A pattern alternative p1 | ... | pn consists of a number of alternative patterns
pi
. All alternative patterns are type checked with the expected type of the pattern.
They may no bind variables other than wildcards. The alternative pattern matches
a value v if at least one its alternatives matches v.

Related

How to make my parser support logic operations and word case-insensitive?

Recently, I am learning the Scala parser combinator. I would like to parse the key in a given string. For instance,
val expr1 = "local_province != $province_name$ or city=$city_name$ or people_number<>$some_digit$"
// ==> List("local_province", "city", "people_number")
val expr2 = "(local_province=$province_name$)"
// ==> List("local_province")
val expr3 = "(local_province=$province_name$ or city=$city_name$) and (lib_name=$akka$ or lib_author=$martin$)"
// ==> List("local_province", "city", "lib_name", "lib_author")
Trial
import scala.util.parsing.combinator.JavaTokenParsers
class KeyParser extends JavaTokenParsers {
lazy val key = """[a-zA-Z_]+""".r
lazy val value = "$" ~ key ~ "$"
lazy val logicOps = ">" | "<" | "=" | ">=" | "<=" | "!=" | "<>"
lazy val elem: Parser[String] = key <~ (logicOps ~ value)
lazy val expr: Parser[List[String]] =
"(" ~> repsep(elem, "and" | "or") <~ ")" | repsep(elem, "and" | "or")
lazy val multiExpr: Parser[List[String]] =
repsep(expr, "and" | "or") ^^ { _.foldLeft(List.empty[String])(_ ++ _) }
}
object KeyParser extends KeyParser {
def parse(input: String) = parseAll(multiExpr, input)
}
Here is my test in Scala REPL
KeyParser.parse(expr1)
[1.72] failure: $' expected but >' found
KeyParser.parse(expr2)
[1.33] parsed: List(local_province)
KeyParser.parse(expr3)
[1.98] parsed: List(local_province, city, lib_name, lib_author)
I notice that the KeyParser only works for "=" and it doesn't support the case like "(local_province<>$province_name$ AND city!=$city_name$)" which contains "<> | !=" and "AND".
So I would like to know how to revise it.
I notice that the KeyParser only works for "="
This isn't quite true. It also works for !=, < and >. The ones it doesn't work for are >=, <= and <>.
More generally it does not work for those operators which have a prefix of them appear in the list of alternatives before them. That is >= is not matched because > appears before it and is a prefix of it.
So why does this happen? The | operator creates a parser that produces the result of the left parser if it succeeds or of the right parser otherwise. So if you have a chain of |s, you'll get the result of the first parser in that chain which can match the current input. So if the current input is <>$some_digit$, the parser logicOps will match < and leave you with >$some_digit$ as the remaining input. So now it tries to match value against that input and fails.
Why doesn't backtracking help here? Because the logicOps parser already succeeded, so there's nowhere to backtrack to. If the parser were structured like this:
lazy val logicOpAndValue = ">" ~ value | "<" ~ value | "=" ~ value |
">=" ~ value | "<=" ~ value | "!=" ~ value |
"<>" ~ value
lazy val elem: Parser[String] = key <~ logicOpAndValue
Then the following would happen (with the current input being <>$some_digit$):
">" does not match the current input, so go to next alternative
"<" does match the current input, so try the right operand of the ~ (i.e. value) with the current input >$some_digit$. This fails, so continue with the next alternative.
... bunch of alternatives that don't match ...
"<>" does match the current input, so try the right operand of the ~. This matches as well. Success!
However in your code the ~ value is outside of the list of alternatives, not inside each alternative. So when the parser fails, we're no longer inside any alternative, so there's no next alternative to try and it just fails.
Of course moving the ~ value inside the alternatives isn't really a satisfying solution as it's ugly as hell and not very maintainable in the general case.
One solution is simply to move the longer operators at the beginning of the alternatives (i.e. ">=" | "<=" | "<>" | ">" | "<" | ...). This way ">" and "<" will only be tried if ">=", "<=" and "<>" have already failed.
A still better solution, which does not rely on the order of alternatives and is thus less error-prone, is to use ||| instead of. ||| works like | except that it tries all of the alternatives and then returns the longest successful result - not the first.
PS: This isn't related to your problem but you're currently limiting the nesting depth of parentheses because your grammar is not recursive. To allow unlimited nesting, you'll want your expr and multiExpr rules to look like this:
lazy val expr: Parser[List[String]] =
"(" ~> multiExpr <~ ")" | elem
lazy val multiExpr: Parser[List[String]] =
repsep(expr, "and" | "or") ^^ { _.foldLeft(List.empty[String])(_ ++ _) }
However I recommend renaming expr to something like primaryExpr and multiExpr to expr.
_.foldLeft(List.empty[String])(_ ++ _) can also be more succinctly expressed as _.flatten.

Haskell own instance typeclass

I need to declare my own typeclass but I dont understand why there is the (==).
data Egg = Soft | Hard
instance Eq Egg where
(==)
I did not find anything where the (==) is used in an instance, only in a class
The easy way to have an instance of Eq is:
data Egg = Soft | Hard deriving Eq
The hard way (with more control):
data Egg = Soft | Hard
instance Eq Egg where
Soft == Soft = True
Hard == Hard = True
_ == _ = False
UPD: Since the equality function (==) as an operator seem to be the confusing bit, here is the same instance written with a prefix notation:
data Egg = Soft | Hard
instance Eq Egg where
(==) Soft Soft = True
(==) Hard Hard = True
(==) _ _ = False
As a quick reminder: operator are infix (in between terms) by default, and functions are prefix (before terms) by default. To make an operator prefix it is surrounded by (), to make a function infix it is surrounded by ``. Here is a thread talking about which characters are used for operator vs functions.
I assume you’re trying to make an instance of the standard typeclass Eq for your custom datatype. The Eq class is defined as:
class Eq a where
(==) :: a -> a -> Bool
a == b = not (a /= b)
(/=) :: a -> a -> Bool
a /= b = not (a == b)
That is, it defines two methods == and /= (which happen to be operators), and provides default implementations of each one in terms of the other. So to make an instance of Eq for your own type, you need to provide an implementation of one or both of these functions (== or /=) for your type. Note that the body of the instance must be indented.
instance Eq Egg where
Soft == Soft = True
Hard == Hard = True
_ == _ = False
Just as you can use a Haskell operator in prefix form by wrapping it in parentheses, e.g., (==) 1 1, you can also implement an operator definition in prefix form:
instance Eq Egg where
(==) Soft Soft = True
(==) Hard Hard = True
(==) _ _ = False
You could even use a case if you so desired:
instance Eq Egg where
(==) a b = case (a, b) of
(Soft, Soft) -> True
(Hard, Hard) -> True
_ -> False
Note that these are all the same as the instance that would be generated for you automatically with deriving:
data Egg = Soft | Hard
deriving (Eq)

Redundant clause in match

When I run the following script:
Definition inv (a: Prop): Prop :=
match a with
| False => True
| True => False
end.
I get "Error: This clause is redundant." Any idea why this happens?
Thanks,
Marcus.
There are quite a few wrong things about this.
False is not a data constructor, and since there is no syntactic difference between data constructors and variable names in Coq, it understands your | False => as a pattern matching anything and giving it the name False, in the same way as you could have written:
Definition inv (a: Prop): Prop :=
match a with
| x => True
| y => False
end.
This is why it tells you that the second clause is redundant (since the first pattern matches everything).
Now another thing you should know is that the type Prop is not inductively-defined, and therefore values of type Prop cannot be matched against anything: in fact it would not make sense, since it is an open type that you keep expanding everytime you define a new inductive property.
So there is no way to write a function inv the way you write it.

Why does Slick require using three equal signs (===) for comparison?

I was reading through coming from SQL to Slick and it states to use === instead of == for comparison.
For example,
people.filter(p => p.age >= 18 && p.name === "C. Vogt").run
What is the difference between == and ===, and why is the latter used here?
== is defined on Any in Scala. Slick can't overload it for Column[...] types like it can for other operators. That's why slick needs a custom operator for equality. We chose === just like several other libraries, such as scalatest, scalaz, etc.
a == b will lead to true or false. It's a client-side comparison. a === b will lead to an object of type Column[Boolean], with an instance of Library.Equals(a,b) behind it, which Slick will compile to a server-side comparison using the SQL "a = b" (where a and b are replaced by the expressions a and b stand for).
== calls for equals, === is a custom defined method in slick which is used for column comparison:
def === [P2, R](e: Column[P2])(implicit om: o#arg[B1, P2]#to[Boolean, R]) =
om.column(Library.==, n, e.toNode)
The problem of using == for objects is this (from this question):
Default implementation of equals() class provided by java.lang.Object compares memory location and only return true if two reference variable are pointing to same memory location i.e. essentially they are same object.
What this means is that two variables must point to the same object to be equal, example:
scala> class A
defined class A
scala> new A
res0: A = A#4e931efa
scala> new A
res1: A = A#465670b4
scala> res0 == res1
res2: Boolean = false
scala> val res2 = res0
res2: A = A#4e931efa
scala> res2 == res0
res4: Boolean = true
In the first case == returns false because res0 and res1 point to two different objects, in the second case res2 is equal to res0 because they point to the same object.
In Slick columns are abstracted in objects, so having column1 == column2 is not what you are looking for, you want to check equality for the value a column hold and not if they point to the same object. Slick then probably translates that === in a value equality in the AST (Library.== is a SqlOperator("="), n is the left hand side column and e the right hand side), but Christopher can explain that better than me.
'==' compare value only and result in Boolean 'True' & 'False
'===' compare completely (i.e. compare value with its data types) and result in column
example
1=='1' True
1==='1' False

&& and || in Scala

since normal operators like +, ::, -> and so on are all methods which can be overloaded and stuff I was wondering if || and && are methods as well. This could theoretically work if this were methods in of the boolean object.
But if they are, why is something like
if (foo == bar && buz == fol)
possible? If the compiler reads from right to left this would invoke && on bar instead of (foo == bar)
6.12.3 Infix Operations An infix operator can be an arbitrary
identifier. Infix operators have
precedence and associativity defined
as follows:
The precedence of an infix
operator is determined by the
operator’s first character. Characters
are listed below in increasing order
of precedence, with characters on the
same line having the same precedence.
(all letters)
|
^
&
< >
= !
:
+ -
* / %
(all other special characters)
That is, operators starting with a
letter have lowest precedence,
followed by operators starting with
‘|’, etc.
There’s one exception to
this rule, which concerns assignment
operators(§6.12.4). The precedence of
an assigment operator is the same as
the one of simple assignment (=). That
is, it is lower than the precedence of
any other operator.
It follows with an explanation of associativity, and how it all combines in a expression with multiple operators. The Scala Reference makes good reading.
Because method starts with = has a higher precedence than method starts with &.
So (foo == bar && buz == fol) will become something like the following:
val tmp1: Boolean = (foo == bar)
val tmp2: Boolean = (buz == fol)
tmp1 && tmp2
Those two are definitely methods in scala.