What does operator % mean in Haskell? - haskell

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)

Related

How can (-) seemingly have two different types?

In ghci, when I type
:t (-)
to figure out the type of (-), it returns
(-) :: Num a => a -> a -> a
However, when I write -1 haskell returns a number, which seems to imply that (-) is of type Num a => a -> a. How can (-) seemingly have two different types?
This was a design decision in the language. -1 is a number, but its usage in this context is not related to the function (-). (As Ackdari mentions in their answer, this usage is related to the function negate.) There are a couple compromises that allow this to work:
You cannot take a right slice of the (-) operator. As a workaround, Haskell provides the subtract function.
You cannot write a negative integer without parentheses unless it is at the beginning of an assignment (e.g. directly after = or ->). This produces a parse error:
let x = 8 * -1
Instead, it should be written as
let x = 8 * (-1)
However, this is fine:
let x = -1 * 8
These were considered to be reasonable tradeoffs to the designers of the language.
The answer is already descirbed in the haskell-wiki, it states
The unary minus is syntactic sugar for the Prelude function negate
so the function (-) is always the a - b function and if you write code like
let x = -y the compiler will translate it to let x = negate y.
Unary minus is special in Haskell. As stated in section 3.4 of the Report:
The special form -e denotes prefix negation, the only prefix operator in Haskell, and is syntax for negate (e). The binary - operator does not necessarily refer to the definition of - in the Prelude; it may be rebound by the module system. However, unary - will always refer to the negate function defined in the Prelude. There is no link between the local meaning of the - operator and unary negation.

Use parentheses to disambiguate an expression like `liftM b ap c`

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.

Haskell application, or section?

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.

How does Haskell know which function can operate first?

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 *.

Why Haskell range needs spaces when using [LT .. GT]?

Why is it that when I do range in Haskell, this works:
[LT .. GT]
but this doesn't:
[LT..GT]
and what does this cryptic error mean:
<interactive>:1:2:
Failed to load interface for `LT':
Use -v to see a list of the files searched for.
<interactive>:1:2:
A section must be enclosed in parentheses thus: (`LT..` GT)
However, When I use Ints, the second form (without spaces) works:
[1..3]
It's because LT.. is interpreted as the . operator in the LT module.
<interactive>:1:2:
Failed to load interface for `LT':
Use -v to see a list of the files searched for.
It means GHC cannot find a module named LT. The same message appears if you use a qualified name with a non-existing library:
Prelude> SDJKASD.sdfhj
<interactive>:1:1:
Failed to load interface for `SDJKASD':
Use -v to see a list of the files searched for.
<interactive>:1:2:
A section must be enclosed in parentheses thus: (`LT..` GT)
In Haskell, a section is an infix operator with a partial application, e.g. (* 3), which is equivalent to \x -> x * 3.
In your case, LT.. is interpreted as an infix . operator, and the GT is part of the section formed with this operator.
A section must be enclosed in parenthesis, and since the misinterpretation does not, the parser will complain like this.
Another example of the error:
Prelude> [* 3]
<interactive>:1:2:
A section must be enclosed in parentheses thus: (* 3)
Because of the maximal munch rule, LT.. gets interpreted as the qualified name of the (.) operator in the LT module. Since you can define your own operators in Haskell, the language allows you to fully qualify the names of operators in the same way as you can with functions.
This leads to an ambiguity with the .. used in ranges when the name of the operator starts with ., which is resolved by using the maximal munch rule, which says that the longest match wins.
For example, Prelude.. is the qualified name of the function composition operator.
> :info Prelude..
(.) :: (b -> c) -> (a -> b) -> a -> c -- Defined in GHC.Base
infixr 9 .
> (+3) Prelude.. (*2) $ 42
87
The reason why [1..3] or [x..y] works, is because a module name must begin with an upper case letter, so 1.. and x.. cannot be qualified names.
Failed to load interface for `LT':
Kenny and Hammar have explained what this means: LT.. is assumed to be the . function in the LT module. Since there is no LT module, your interpreter naturally cannot load it.
A section must be enclosed in parentheses thus: (LT.. GT)
Along the same vein, assuming that LT.. is a reference to the . function in the LT module, your interpreter is apparently assuming that you made the mistake of using square brackets instead of parens in order to for a "section" ( a section is, for example, (+1) ).
This is simply an obnoxious little wart in the Haskell language; just remember to use spaces.

Resources