How can (-) seemingly have two different types? - haskell

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.

Related

Haskell: What are the types of these expressions (if they have any)?

I'm new to haskell and I am doing some exercises to learn as much as I can about types, but some of the questions are really confusing to me. The exercise I'm struggling with reads:
What are the types of the following expressions? If the expression has no type, do state as much. Also
be sure to declare necessary class restrictions where needed.
5 + 8 :: ?
(+) 2 :: ?
(+2) :: ?
(2+) :: ?
I get that 5 + 8 will return an Int, but the others are not valid expressions by them selves. Does that mean that they have no type, or should i think of them as functions (f :: Int -> Int)(f x = x + 2)?
First, the answers:
5 + 8 has the type forall a. Num a => a which can be specialized to Int.
(+) 2 and (2 +) are the same and both have the type forall a. Num a => a -> a which can be specialized to Int -> Int.
(+ 2) is different but also has the type forall a. Num a => a -> a which can be specialized to Int -> Int.
(+) has the type forall a. Num a => a -> a -> a which can be specialized to Int -> Int -> Int.
For further explanation, read on.
One Literal, Many Types
In Haskell, a numeric literal like 114514 does not have a concrete type like Int. This is good because we have many different types for numbers, incl. Int, Integer, Float, Double and so on, and we do not want to have different notations for each type.
The literals 5, 114514, and 1919810 all have the type
forall a. Num a => a
You can read it like this: "for any type a, if a is an instance of the Num typeclass, then the value can have the type a." Int, Integer, Float and Double are all instances of Num, and because Haskell has (relatively) strong type inference, in different contexts it will be specialized to concrete types like Int.
So what is typeclass?
Typeclasses
The way we express some type "supports" some operation(s) in Haskell is by typeclasses. A typeclass is a set of function signatures, without real implementations. They represent operations we want to make on some types (e.g. Num represents operations we want to make on numeric types), but the actual implementations on different types may differ (the actual calculation of integers and floating point numbers are really different).
We can make a type be an instance of a typeclass (note that this has nothing to do with the instances and classes in object-oriented programming), by actually defining these functions for this type. In this way, we defined this type to support these operations.
Num is one of the typeclasses, which represents the support of numeric operations. It is partially defined as below (I did not put the full one here, in order to reduce verbosity):
class Num a where
(+) :: a -> a -> a
(-) :: a -> a -> a
(*) :: a -> a -> a
You can see that in the signatures we have as instead of real concrete types, these functions are said to be polymorphic, that is, they are generic and can be specialized to different types.
For example, if a and b are both Ints, then a + b has type Int too, because haskell inferred that the + we used here should be the one defined for Int, given that both of its arguments are Ints.
So, if some type is an instance of Num, it means that the +, - and * operator is defined for this type. Being an instance of Num means supporting these operators.
Sections
One good thing of Haskell is its (relatively) flexible infix operators. In Haskell, infix operators are nothing but normal functions with an infix notation (which is merely a syntactic sugar). We can also use infix operators in a prefix manner. For example, 5 + 8 is equivalent to (+) 5 8.
It seems that you are confused with (+) 5, (+5) and (5+). Remember that if we put parentheses on both sides of an infix function, we make it prefix. And as you may already know, prefix functions can be partially applied, that is, give the function only some of its parameters, so it becomes a functions with less parameters to be given later. (+) 5 means that we partially applied (+) by only giving its first argument, so it becomes a function waiting for another one argument, or originally its second argument. We can apply (+) 5 to 8 so it becomes ((+) 5) 8, which is equivalent to 5 + 8.
On the other hand, (5+) and (+5) are called sections, which are another syntactic sugar for infix operators. (5+) means you filled the left hand side of the operator, and it becomes a function waiting for its right hand side. (5+) 8 means 5 + 8 or (+) 5 8. (+5) is flipped, i.e. you filled the right hand side, so it is a function waiting for the left hand side. (+5) 8 means 8 + 5 or (+) 8 5.
Haskell is a language very different from other languages you may have learned; every expression that compiles has a type. Functions are first-class and every function has a type too. Thinking in types will really help in your learning progress.
In Haskell:
operators are just functions
functions can be provided less arguments then declaration
parenthesis can be used to disambiguate order and components of arguments
Taken together it means that:
(+) Is just + function, and will take 2 more arguments
(1 +) Is function with it's first argument provided and will take one more
(+ 2) Is another function that have is argument provided, but this time second one. It also awaits one more argument

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

What does operator % mean in 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)

Haskell type dessignation

I have to dessignate types of 2 functions(without using compiler :t) i just dont know how soudl i read these functions to make correct steps.
f x = map -1 x
f x = map (-1) x
Well i'm a bit confuse how it will be parsed
Function application, or "the empty space operator" has higher precedence than any operator symbol, so the first line parses as f x = map - (1 x), which will most likely1 be a type error.
The other example is parenthesized the way it looks, but note that (-1) desugars as negate 1. This is an exception from the normal rule, where operator sections like (+1) desugar as (\x -> x + 1), so this will also likely1 be a type error since map expects a function, not a number, as its first argument.
1 I say likely because it is technically possible to provide Num instances for functions which may allow this to type check.
For questions like this, the definitive answer is to check the Haskell Report. The relevant syntax hasn't changed from Haskell 98.
In particular, check the section on "Expressions". That should explain how expressions are parsed, operator precedence, and the like.
These functions do not have types, because they do not type check (you will get ridiculous type class constraints). To figure out why, you need to know that (-1) has type Num n => n, and you need to read up on how a - is interpreted with or without parens before it.
The following function is the "correct" version of your function:
f x = map (subtract 1) x
You should be able to figure out the type of this function, if I say that:
subtract 1 :: Num n => n -> n
map :: (a -> b) -> [a] -> [b]
well i did it by my self :P
(map) - (1 x)
(-)::Num a => a->a->->a
1::Num b=> b
x::e
map::(c->d)->[c]->[d]
map::a
a\(c->d)->[c]->[d]
(1 x)::a
1::e->a
f::(Num ((c->d)->[c]->[d]),Num (e->(c->d)->[c]->[d])) => e->(c->d)->[c]->[d]

Resources