(First of all this is not HW, I have all the answers)
I have a simple BNF grammar
<UNIT> ::= ( <CLAUSE> ) | a | b | c
<ITEM> ::= not <UNIT> | <UNIT>
<CLAUSE> ::= <CLAUSE> and <PHRASE> | <PHRASE>
<PHRASE> ::= <ITEM> | <ITEM> or <PHRASE>
and operator is Left associative (left-hand recursive )
or operator is Right associative (this time, it is right-hand recursive )
Given expression c and b or not a and ( not b or c ), why is most right "and" is higher in the parse tree ?
The way, I see c **and** b or not a and ( not b or c ) left most should be higher in the parse tree.
Our professor provided this answer:
Here is the parse tree in a lispy notation.
(clause (clause (clause (phrase (item (unit 'c'))))
'and'
(phrase (item (unit 'b'))
'or'
(phrase (item 'not'
(unit 'a')))))
**'and'** // is higher in parse tree
(phrase (item (unit '('
(clause (phrase (item 'not’(unit 'b'))
'or'
(phrase (item (unit 'c')))))
')' ))))
The BNF grammar given seems consistent with the parse tree, and consistent with the claim that "and" is supposed to be left-associative. If you want to produce "a and b and c" using this grammar, starting with "Clause", you start this way:
Clause
Clause and Phrase
At which point, Phrase cannot become "b and c" (without parentheses) because only clauses can produce "and". Phrase has to develop into "c", and the Clause on the second line can become "a and b". This will force the rightmost "and" to be higher in the parse tree.
Since higher elements in the parse tree are last to evaluate, this is consistent with the claim that the operator "and" is left associative.
Related
I'm reading up on Haskell and as expected there are some operators that are left associative and others that are right associative. That got me thinking, how would the implementation differ for a new operator ¤, when comparing the left associative version versus the right associative version?
So given [1,2] ¤ [3,4] ¤ [5,6], what changes in the implementation if I want this to be interpreted as (([1,2] ¤ [3,4]) ¤ [5,6]) versus ([1,2] ¤ ([3,4] ¤ [5,6]))?
To state that an operator is left- or right-associative, one can use a fixity declaration.
For instance
infixl 5 .+. -- left associative
infixr 5 .-. -- right associative
infix 5 .=. -- not associative
The last one causes x .=. y .=. z to be a parse error, requiring explicit parentheses.
The number 5 above is the precedence level, and should be chosen following the level of other operators (e.g. (+) is level 6, while ($) has level 0).
Let:
data Some a b = Some a b deriving (Show)
Then (in ghci):
> Some (id 1) (id 2)
Some 1 2
But (not surprisingly):
> Some id 1 id 2
Couldn't match expected type ‘(a1 -> a1) -> Integer -> t’ ...
However:
> id 1 `Some` id 2
Some 1 2
Why is that? Does fixity of infix value constructors defaults to the lowest?
A constructor is a function as well: we can use a constructor C as a function that takes the parameters the constructor is going to hold as arguments, and then constructs a new instance of the type. So in your example, Haskell syntactically sees Some like it sees any function.
If you write a function between backquotes (`), then it acts like an operator, like it is written in Section 3 of the Haskell '98 report:
An operator is either an operator symbol, such as + or $$, or is an ordinary identifier enclosed in grave accents (backquotes), such as `op`. For example, instead of writing the prefix application op x y, one can write the infix application x `op` y. If no fixity declaration is given for `op` then it defaults to highest precedence and left associativity.
The section also describes that function application has priority over operators. We see that an expression exp can be a fexp (an function application expression). The arguments of such function application are aexps. An aexp can contain an operator (through exp), but only in case it is between brackets (()), square brackets ([], when we construct a list), etc. But not without a specification of priority. If we write: f a b + g x a, it is thus interpreted as (f a b) + (g x y), not as f a (b+g) x y.
Now the only question that is still open is what happens in case the expression contains other operators. In Haskell we assign precedence (and associativty) to operators. This is described in Section 4 of the Haskell '98 report. All operators are assigned a precedence between 0 and 9. The * operator has for instance higher precedence than +, and that means that 2 + 3 * 2 is interpreted as 2 + (3 * 2), and not as (2 + 3) * 2. As is described in the quoted section, if you do not specify the precedence, then it is the highest. So 1 + id 2Someid 3 * 5 is interpreted as 1 + (((id 2) `Some` (id 3)) * 5) (but this makes no sense here, since we can not multiply a Some object with 5.
So your expression:
id 1 `Some` id 2
is equivalent to:
Some (id 1) (id 2)
From Thinking Functionally with Haskell, pg 67:
[...] list comprehensions are translated into equivalent definitions in
terms of map and concat. The translation rules are:
[e | True] = [e]
[e | q] = [e | q, True]
[e | b, Q] = if b then [e | Q] else []
[e | p <- xs, Q] = let ok p = [e | Q]
ok _ = []
in concat (map ok xs)
The author nowhere defines e, q, Q, or b. I take it that the first means "expression," but I've never seen the others before. Could someone please enlighten me?
This translation comes straight out of the official Haskell Report, which has this additional sentence:
where e ranges over expressions, p over patterns, l over list-valued expressions, b over boolean expressions, decls over declaration lists, q over qualifiers, and Q over sequences of qualifiers. ok is a fresh variable. The function concatMap, and boolean value True, are defined in the Prelude.
If you wonder what any of those terms means, the Report has further details.
I would guess that:
e is any expression, as you say
q is any expression with type Bool
b is also any expression with type Bool (this seems a bit strange, though, perhaps I'm wrong...)
p is any pattern. For example, Right x, Just _, x#(y,z)
Q is a bunch of list comprehension elements separated by commas. By "list comprehension element" I mean either guards (i.e. expressions of type Bool) or pattern matches, e.g x <- xs, Right x <- xs.
In haskell I can see a lot of prime just like 'chainl1'
what does it mean?
expr = term `chainl1` addop
term = factor `chainl1` mulop
factor = parens expr <|> integer
mulop = do{ symbol "*"; return (*) }
<|> do{ symbol "/"; return (div) }
addop = do{ symbol "+"; return (+) }
<|> do{ symbol "-"; return (-) }
The prime (') is treated like any number in variable names, i.e. unless it's at the beginning you can use it just like a letter. Hence names such as foldl'; generally those will refer some kind of "alternative" of a similar thing, in this case foldl which is equivalent except for lazy evaluation.
However, there aren't actually any primes in your examples. Those are backticks. Surrounding a function with backticks lets you use it like an infix operator, e.g.
plus :: Int -> Int -> Int
plus = (+)
Prelude> 4 `plus` 5
9
A binary function f is usually applied to 2 arguments as f x y. However, there are certain binary functions (like elem) for which it makes sense to see them infix and not postfix. To move a binary function to infix notation one encloses it in backticks (`). Compare
intersect set1 set2 = [x | x <- set1, elem x set2]
with
intersect set1 set2 = [x | x<- set1, x `elem` set2]
The second one is closer to the mathematical notation.
See also the corresponding learn you a Haskell chapter
PS: You can do the reverse for operators. Usually an operator is infix (2 + 3) but you can move it to prefix by enclosing it in parens ((+) 2 3)
I am new to Haskell and this mixture of Infix and Prefix notation is confusing me.
What is the difference between an operator like '+' and a function like head? How do I write an operator 'c' which does this 1 c 1 = 2?
I found this definition a ! b = True. How does Haskell know that I am defining ! and not a function a?
In Haskell, to create an operator you must use the following "operator symbols":
! # $ % * + . / < = > ? \ ^ | : - ~
So, for example
($$$) a b = a+b
Defines an operator $$$ which can be used in the expression 1 $$$ 1 to yield a value of 2.
Conceptually, there is no difference between an operator and a function, and you can use backticks or parens to make one work like the other.
EDIT:
Just so it is 100% clear, let me demonstrate turning a function into an operator and vice versa:
For the operator '+', the following two expressions are equivalent:
1+1
(+) 1 1
Similarly, for a function, the following two expressions are equivalent:
foo 1 2
1 `foo` 2
Haskell knows you aren't defining a function called a because the ! wouldn't be valid in a function argument list. In order to use the ! not as an operator but just as a normal identifier, you need to enclose it in parentheses. If you wrote instead a (!) b = True, then it would define the function a :: t -> t1 -> Bool.
This is the entire difference between operators and normal identifiers in Haskell — there are special syntax rules for operators that allow them to be used infix without backticks. Otherwise, they're just functions.
Really, the only difference is syntax. Function names begin with a lower-case letter, followed by a series of alpha-numeric characters. Operators are some unique sequence of the typical operator characters (+ - / * < > etc.).
Functions can be used as operators (in-fix) by enclosing the function name in ` characters. For example:
b = x `elem` xs -- b is True if x is an element in xs.
Operators can be used as functions (pre-fix) by enclosing the operator in parens. For example:
n = (+) 2 5 -- n = 2 + 5, or 7.