While in Haskell, the following works:
> (+) `liftM` (Just 3) `ap` (Just 5)
Just 8
Frege hints to use parantheses:
frege> (+) `liftM` (Just 3) `ap` (Just 5)
E <console>.fr:12: invalid expression, none-associative operator liftM
found on same level as none-associative operator ap
H <console>.fr:12: Use parentheses to disambiguate an expression like a
liftM b ap c
I found this section in Haskell report:
Expressions involving infix operators are disambiguated by the
operator's fixity (see Section 4.4.2). Consecutive unparenthesized
operators with the same precedence must both be either left or right
associative to avoid a syntax error. Given an unparenthesized
expression "x qop(a,i) y qop(b,j) z", parentheses must be added around
either "x qop(a,i) y" or "y qop(b,j) z" when i=j unless a=b=l or
a=b=r.
In the code above, both the "operators" have no associativity and have the same default precedence so it seems like Frege's behavior is consistent with Haskell report.
Am I understanding this right? Why Frege needs parentheses in this case whereas Haskell is able to disambiguate? or How is Haskell able to disambiguate in this case?
Well, this is because, as it stands, `foo` defaults to non-associativity In Frege, while in Haskell is it left associativity.
This should be corrected in the Frege compiler in order to make it more Haskell compatible.
Related
I'm learning haskell, and I have a lot of difficulty with mentally parsing many haskell expressions I come across.
Of course, I expect that, with enough practice, mentally parsing haskell will become second-nature, but in the meantime, in order to make sense of what I come across, I'd like to find some automatic way to translate an arbitrary "standard haskell"1 expression into one in which all "ambiguous"2 sub-expressions have been eliminated by introducing the necessary parentheses.
For example, it would translate the expression
f g h i
...into
((f g) h) i
..., or
a -> b -> c -> d
...into
a -> (b -> (c -> d))
..., etc.
Preferably, this would be a tool I can access with my phone, since I do much of my reading on haskell away from a proper computer.
1Of course, no such tool could possibly work with custom operators of unknown fixity and associativity. By "standard haskell" I mean the stuff defined in the prelude and in the standard haskell library.
2I'm using "ambiguous" here as shorthand for "ambiguous in the absence of precedence rules". E.g. 2 + 3 * 5 is ambiguous unless there's some precedence rule that settles the question of which of the two operations will be performed first.
If you really want to go to the work of it, you could write a TemplateHaskell function to do this for you - you essentially just walk the AST and add parens at will. I started doing that, but realized it will get pretty long and tedious pretty fast. I think it may be more convenient for the moment for you to only think about currying when it actually comes into play (with functions that are not fully applied).
However, there is a trick you can use for a subcase of your problem: parens around operators whose fixity and associativity you aren't familiar with. In GHCi, after booting up with the right flags, just wrap the expression you are interested in inspecting in $([| <expression> |]). Then, you get to see a parenthesized version of your expression before the result of evaluating it.
$ ghci -ddump-splices -XTemplateHaskell
Prelude> $([| 1 + 2 ^ 3 * 4 |])
<interactive>:1:3-21: Splicing expression
[| 1 + 2 ^ 3 * 4 |] ======> (1 + ((2 ^ 3) * 4))
33
Prelude> $([| 1 <$ pure 4 >>= \x -> const mempty =<< [(+),(*)] <*> [1,2] <* [False] |])
<interactive>:2:3-77: Splicing expression
[| 1 <$ pure 4
>>=
(\ x_a6PT -> const mempty =<< [(+), (*)] <*> [1, 2] <* [False] |]
======>
((1 <$ (pure 4))
>>=
(\ x_a6PT
-> ((const mempty) =<< (([(+),(*)] <*> [1,2]) <* [False]))))
[]
Prelude>
However, this definitely won't fix the type signatures or function applications the way you want.
It's not exactly what you're asking for, but I've found using HLint to warn me about unnecessary parens when I'm writing Haskell to be a big help when I'm reading.
You may also find the chart on page 23 of Bernie Pope's "A tour of the Haskell Prelude" helpful. I've included a copy below.
I wanted to flip a list constructor usage, to have type:
[a] -> a -> [a]
(for use in a fold), so tried:
(flip :)
but it gives the type:
Prelude> :t (flip :)
(flip :) :: [(a -> b -> c) -> b -> a -> c] -> [(a -> b -> c) -> b -> a -> c]
This surprised me, but it appears that this was parsed as a left section of (:), instead of a partial application of flip. Rewriting it using flip as infix seems to overcome this,
Prelude> :t ((:) `flip`)
((:) `flip`) :: [a] -> a -> [a]
But I couldn't find the rule defining this behavior, and I thought that function application was the highest precedence, and was evaluated left->right, so I would have expected these two forms to be equivalent.
What you want to do is this:
λ> :t (flip (:))
(flip (:)) :: [a] -> a -> [a]
Operators in Haskell are infix. So when you do flip : it operates in an infix fashion i.e. flip is applied to : function. By putting parenthesis explicitly in flip (:), you tell that : should be applied to flip. You can also use the backtick operator in flip for making that infix which you have tried already.
It was putting : in parentheses that made your second example work, not using backticks around flip.
We often say that "function application has highest precedence" to emphasise that e.g. f x + 1 should be read as (f x) + 1, and not as f (x + 1). But this isn't really wholly accurate. If it was, and (flip :) parsed as you expected, then the highest precedence after (f x) + 1 would be the application of (f x) to +; the whole expression f x + 1 would end up being parsed as f applied to 3 arguments: x, +, and 1. But this would happen with all expressions involving infix operators! Even a simple 1 + 1 would be recognised as 1 applied to + and 1 (and then complain about the missing Num instance that would allow 1 to be a function).
Essentially this strict understanding of "function application has highest precedence" would mean that function application would be all that ever happens; infix operators would always end up as arguments to some function, never actually working as infix operators.
Actually precedence (and associativity) are mechanisms for resolving the ambiguity of expressions involving multiple infix operators. Function application is not an infix operator, and simply doesn't take part in the precedence/associativity system. Chains of terms that don't involve operators are resolved as function application before precedence is invoked to resolve the operator applications (hence "highest precedence"), but it's not really precedence that causes it.
Here's how it works. You start with a linear sequence of terms and operators; there's no structure, they were simply written next to each other.
What I'm calling a "term" here can be a non-operator identifier like flip; or a string, character, or numeric literal; or a list expression; or a parenthesised subexpression; etc. They're all opaque as far as this process is concerned; we only know (and only need to know) that they're not infix operators. We can always tell an operator because it will either be a "symbolic" identifier like ++!#>, or an alphanumeric identifier in backticks.
So, sequence of terms and operators. You find all chains of one or more terms in a row that contain no operators. Each such chain is a chain of function applications, and becomes a single term.1
Now if you have two operators directly next to each other you've got an error. If your sequence starts or ends in an operator, that's also an error (unless this is an operator section).
At this point you're guaranteed to have a strictly alternating sequence like term operator term operator term operator term, etc. So you pick the operator with the highest precedence together with the terms to its left and right, call that an operator application, and those three items become a single term. Associativity acts as a tie break when you have multiple operators with the same precedence. Rinse and repeat until the whole expression has become a single term (or associativity fails to break a tie, which is also an error). This means that in an expression involving operators, the "top level application" is always one of the operators, never ordinary function application.
A consequence of this is that there are no circumstances under which an operator can end up passed as the argument to a function. It's simply impossible. This is why we need the (:) syntax to disable the "operator-ness" of operators, and get at their identity as values.
For flip : the only chain of non-operator terms is just flip, so there's no ordinary function application to resolve "at highest precedence". : then goes looking for its left and right arguments (but this is a section, so there's no right argument), and finds flipon its left.
To make flip receive : as an argument instead of the other way around, you must write flip (:). (:) is not an operator (it's in parentheses, so it doesn't matter what's inside), and so we have a chain of two terms with no operators, so that gets resolved to a single expression by applying flip to (:).
1 The other way to look at this is that you identify all sequences of terms not otherwise separated by operators and insert the "function application operator" between them. This "operator" has higher precedence than it's possible to assign to other operators and is left-associative. Then the operator-resolution logic will automatically treat function application the way I've been describing.
I want to update a record using lens with a value parsed by attoparsec.
fmap (myRecord & _2 . someField .~) double
And it totally doesn't work:
Iddq3.hs:99:48:
The operator ‘.~’ [infixr 4] of a section
must have lower precedence than that of the operand,
namely ‘&’ [infixl 1]
in the section: ‘myRecord & _2 . someField .~’
What does this error mean? What are infixr and infixl? How can I rewrite the function to correct it?
You just can't mix operators of that fixity. Fixity in Haskell is just operator precedence, just like your "Please Excuse My Dear Aunt Sally" (if you're American, this is probably what you learned) for remembering what order to apply operations in, i.e. Parentheses, Exponent, Multiplication, Division, Addition, Subtraction. Here, the .~ operator is said to have a higher right associative precedence than the left associative low precedence of the & operator. The real problem comes from mixing the right and left associative operators, the compiler doesn't know what order to apply them in!
Instead, you can re-formulate it as two operator sections composed together
fmap ((myRecord &) . (_2 . someField .~)) double
So that you give the compiler an explicit grouping, or you can use the prefix set function for a cleaner look
fmap (\v -> set (_2 . someField) v myRecord) double
Or if you want to get rid of the lambda (my preference is to leave it alone), you can use flip as
fmap (flip (set (_2 . someField)) myRecord) double
This is a somewhat strange restriction on the way operators can be used in sections.
Basically, when you have an operator section like (e1 & e2 .~), there are two ways you can imagine desugaring it to sectionless notation. One is to turn the operator into prefix position:
(.~) (e1 & e2)
(If the operator were in front, a flip would also need to be added.)
The other way is to turn it into a lambda expression:
\x -> e1 & e2 .~ x
These two ways of thinking of sections are supposed to give the same result.
There's a problem, though, if as here, there is another operator & of lower fixity/precedence than the sectioned operator. Because that means the lambda expression parses as
\x -> e1 & (e2 .~ x)
In other words, the lambda expression definitely isn't equivalent to simply moving the operator and keeping the rest as a unified expression.
While the Haskell designers could have chosen to interpret a section in one of the two ways, instead they chose to disallow sections where the two interpretations don't match, and make them errors. Possibly because, as I understand it, the lambda expression interpretation is more intuitive to humans, while the operator movement is easier to implement in a parser/compiler.
You can always use the lambda expression explicitly, though, or make your own point-free version like #bheklilr showed.
I'm writing a custom language that features some functional elements. When I get stuck somewhere I usually check how Haskell does it. This time though, the problem is a bit to complicated for me to think of an example to give to Haskell.
Here's how it goes.
Say we have the following line
a . b
in Haskell.
Obviously, we are composing two functions, a and b. But what if the function a took another two functions as parameters. What's stopping it from operating on . and b? You can surround it in brackets but that shouldn't make a difference since the expression still evaluates to a function, a prefix one, and prefix functions have precedence over infix functions.
If you do
(+) 2 3 * 5
for example, it will output 25 instead of 17.
Basically what I'm asking is, what mechanism does Haskell use when you want an infix function to operate before a preceding prefix function.
So. If "a" is a function that takes two functions as its parameters. How do you stop Haskell from interpreting
a . b
as "apply . and b to the function a"
and Interpret it as "compose functions a and b".
If you don't put parens around an operator, it's always parsed as infix; i.e. as an operator, not an operand.
E.g. if you have f g ? i j, there are no parens around ?, so the whole thing is a call to (?) (parsed as (f g) ? (i j), equivalent to (?) (f g) (i j)).
I think what you're looking for are fixity declarations (see The Haskell Report).
They basically allow you to declare the operator precedence of infix functions.
For instance, there is
infixl 7 *
infixl 6 +
which means that + and * are both left associative infix operators.
* has precedence 7 while + has precendence 6, i.e * binds stronger than +.
In the report page, you can also see that . is defined as infixr 9 .
Basically what I'm asking is, what mechanism does Haskell use when you
want an infix function to operate before a preceding prefix function.
Just to point out a misconception: This is purely a matter of how expressions are parsed. The Haskell compiler does not know (or: does not need to know) if, in
f . g
f, g and (.) are functions, or whatever.
It goes the other way around:
Parser sees f . g (or, the syntactically equivalent: i + j)
Hands this up as something like App (App (.) f) g following the lexical and syntax rules.
Only then, when the typechecker sees App a b it concludes that a must be a function.
(+) 2 3 * 5
is parsed as
((+) 2 3) * 5
and thus
(2 + 3) * 5
That is, because function applications (like (+) 2 3) get evaluated first, before functions in infix notation, like *.
I want to know what the Haskell operator % does. It is hard to find on google, I could not find it in the Haskell Report either.
I saw it used in this piece of code:
fi=zz.bu
bu=zz.(:).(++"zz")
[]#zz=zz;zz#__=zz
zZ%zz=zZ zz$zZ%zz
zz=(([[],[]]++).)
zZ=zipWith;z=zZ((#).show)[1..]$zZ(++)(bu%"Fi")(fi%"Bu")
taken from: https://codegolf.stackexchange.com/questions/88/obfuscated-fizzbuzz-golf/110#110
Here is the relevant section of the Haskell Report:
Haskell provides special syntax to support infix notation. An operator is a function that can be applied using infix syntax (Section 3.4), or partially applied using a section (Section 3.5).
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 (see Section 4.4.2).
Dually, an operator symbol can be converted to an ordinary identifier by enclosing it in parentheses. For example, (+) x y is equivalent to x + y, and foldr (*) 1 xs is equivalent to foldr (\x y -> x * y) 1 xs.
That is to say, there is nothing special about "operators" in Haskell other than their syntax. A function whose name is made from symbols defaults to infix, a function whose name is alphanumeric defaults to prefix, and either can be used in the other style with a bit of extra syntax.
Incidentally, since it's often impossible to search based on operator names using Google, to find operators that are declared in the standard libraries there are two search engines specifically for finding things on Hackage.
In general, we can define a new function foo like so:
foo a b c = (something involving a, b, and c)
Similarly, we can define a binary operator % (constructed out of any combination of symbol characters) like so:
a % b = (something involving a and b)