I have seen Haskell code like this:
infix 4 ~=
(~=) :: Double -> Double -> Bool
x ~= y = abs (x-y) < epsilon
where epsilon = 1 / 1000
Despite that I know what this code is doing, I would like to know what infix 4 means.
That is a fixity declaration:
A fixity declaration gives the fixity and binding precedence of one or more operators.
In particular the infix part of infix 4 ~= means that the operator ~= is not right or left associative, so x ~= y ~= z is not a valid expression.
And the precedence is 4 which means that it binds tighter than for example &&, so x ~= y && z parses as (x ~= y) && z, but less tight than for example ++, so x ~= y ++ z parses as x ~= (y ++ z) (but that fails to type check). In that respect it is the same as comparison operators like ==, so also x == y ~= z will give a parse error.
Here is a table of the fixities of standard operators (from the Haskell 2010 report linked above):
Precedence
Left associative
Non-associative
Right associative
9
!!
.
8
^ , ^^ , **
7
*, /, ‘div‘, ‘mod‘, ‘rem‘, ‘quot‘
6
+, -
5
:, ++
4
==, /=, <, <=, >, >=, ‘elem‘, ‘notElem‘
3
&&
2
||
1
>>, >>=
0
$, $!, ‘seq‘
Related
Just ran into something that seems strange to me. Backticks function as something like a syntactic operator.
applyOp :: Int -> (Int -> Int -> Int) -> Int -> Int
applyOp x op y = x `op` y
> applyOp 2 (+) 5
7
I was surprised to see this. I had always imagined that backticks were required to surround an operator symbol or identifier, not an identifier which can be bound during execution to an operator. Am I thinking about this the wrong way?
Backticks are syntax sugar that turns an identifier into an infix operator. That is to say, a `f` b = f a b is the general rewrite rule. This is useful for clarity, but also allows one to avoid too many brackets, since f (a b) (c d) can be rewritten as a b `f` c d.
However there are a few caveats with using these, but only two restrictions:
The backticked expression must be an identifier, so 1 `mod` 2 is valid, but a `zipWith (+)` b is not valid, because it involved a function application.
Only alphanumeric identifiers can be backticked, so 1 `mod` 2 is valid, but 1 `(+)` 2 is invalid. You could see this as an application of the previous restriction.
Backticked expressions have precedence 9, and are left-associative, so a `f` b `f` c is parsed as (a `f` b) `f` c, and in general other operators will inlcude it, so a +
c `f` b is parsed as a + (c `f` b)*
In this case, applyOp x op y = x `op` y is valid, since op is an alphanumeric identifier, and this is equivalent to applyOp x op y = op x y. Note that there is no restriction on binding pattern-matched identifiers!
*This is untrue for the standard Prelude operators !! and .. More info of precedence and fixity can be found in The Haskell 98 Report.
I have the following two Haskell expressions:
map (\f x -> f x 5) [(-),(+),(*)]
map (\f x -> f 5 x) [(-),(+),(*)]
And I'm trying to figure out whether either expression above is equivalent to the following expression:
map ($ 5) [(-),(+),(*)]
I am trying to understand what the difference between the first two expressions is.
Since for both expressions, there is only one parameter passed to the lambda function (e.g. the operator), the function will be partially applied.
Is it correct to say that the elements in the result list from the first expression will be:
(1) - x 5 = (- x) 5
(2) + x 5 = (+ x) 5
(3) * x 5 = (* x) 5
And for the second expression:
(1) - 5 x = (- 5) x
(2) + 5 x = (+ 5) x
(3) * 5 x = (* 5) x
However, I don't think that either expression is equivalent to map ($ 5) [(-),(+),(*)]. This is because (- x) 5 (where x is a number) gives an error in GHCI and is an invalid expression. Similarly (- 5) x also gives an error.
On the other hand, map ($5) [(-)], results in a function that takes a number and subtracts it from 5.
Is this reasoning correct? Any insights are appreciated.
(- 5) 5 gives out an error because prefix minus is a special case in the language syntax: (- 5) means minus five, the number, and not a function that subtracts five (see also: Currying subtraction). That being so, I will focus on the (+) case, which is not exceptional.
In your second expression, map (\f x -> f 5 x) [(-),(+),(*)], the second element of the result list will be:
(\f x -> f 5 x) (+)
When evaluating such a thing by hand, it is important to be careful to not mix up prefix, infix and sectioned uses of operators. Application here gives out...
\x -> (+) 5 x -- Prefix syntax (note the parentheses around the operator)
... which is equivalent to...
\x -> 5 + x -- Infix syntax
... and to:
\x -> (5 +) x -- Left section
\x -> (+ x) 5 -- Right section
(5 +) -- Left section, pointfree
So the sections, which are patterned after infix usage of the operators, should be the other way around relative to your question. As for map ($ 5) [(-),(+),(*)], it is equivalent to map (\f x -> f 5 x) [(-),(+),(*)], your second expression. You can confirm that by using the fact that ($) f x = f x to figure out what the ($ 5) right section is.
Just ran into something that seems strange to me. Backticks function as something like a syntactic operator.
applyOp :: Int -> (Int -> Int -> Int) -> Int -> Int
applyOp x op y = x `op` y
> applyOp 2 (+) 5
7
I was surprised to see this. I had always imagined that backticks were required to surround an operator symbol or identifier, not an identifier which can be bound during execution to an operator. Am I thinking about this the wrong way?
Backticks are syntax sugar that turns an identifier into an infix operator. That is to say, a `f` b = f a b is the general rewrite rule. This is useful for clarity, but also allows one to avoid too many brackets, since f (a b) (c d) can be rewritten as a b `f` c d.
However there are a few caveats with using these, but only two restrictions:
The backticked expression must be an identifier, so 1 `mod` 2 is valid, but a `zipWith (+)` b is not valid, because it involved a function application.
Only alphanumeric identifiers can be backticked, so 1 `mod` 2 is valid, but 1 `(+)` 2 is invalid. You could see this as an application of the previous restriction.
Backticked expressions have precedence 9, and are left-associative, so a `f` b `f` c is parsed as (a `f` b) `f` c, and in general other operators will inlcude it, so a +
c `f` b is parsed as a + (c `f` b)*
In this case, applyOp x op y = x `op` y is valid, since op is an alphanumeric identifier, and this is equivalent to applyOp x op y = op x y. Note that there is no restriction on binding pattern-matched identifiers!
*This is untrue for the standard Prelude operators !! and .. More info of precedence and fixity can be found in The Haskell 98 Report.
I am reading Learn You a Haskell, which contains 5 /= 5. I am not so sure what this means. Does the first expression mean 5 / 5 = 5? But, then, it shouldn't be True.
It means not equal. So 5 /= 5 is false as 5 == 5 is true.
x /= y = not (x == y)
As suggested, it recalls the mathematical symbol "≠" (/=) opposite to "=" (==).
The == operator means "is equal".
The /= operator means "is not equal".
It's supposed to be reminiscent of the mathematical "≠" symbol (i.e., an equals sign with a diagonal line through it).
It's the "not equal to" operator.
Various languages use for example !=,<>, etc... and Haskell uses /= ;)
Using :t can tell you the type:
> :t (/=)
(/=) :: Eq a => a -> a -> Bool
So I was reading through a Haskell guide online, and was just curious about the combination of infix operators and filter.
Say you have a function like
filter (>5) [6, 10, 5]
That will return [6,10], which seems like the intuitive way filter should work.
However, doing
filter ((>) 5) [6, 10, 5]
returns an empty list (this still makes sense, (>) checks if its first argument is larger than the second argument).
However, filter is typically defined something like
filter :: (a -> Bool) -> [a] -> [a]
filter _ [] = []
filter p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
When the type system knows it has an infix operator, are most of those infix operators written so that a partially applied function needs a leading argument to the original prefix function? i.e. is infix > defined as something like (butchered syntax)
infix> :: Int -> Int-> Bool
infix> x y = (>) y x
x infix> y = (>) x y
Sorry if this question doesn't make sense, I feel like I'm missing something basic in how p x is evaluated when p is a partially applied infix operator.
(>5) and ((>) 5) are two different types of expression.
The first is what is known as a section. Sections are of the form (op exp) or (exp op) where op is an infix operator and exp is another expression. A section takes an argument and applies it on the missing side, so (>5) 4 = (4 > 5) and (5>) 4 = (5 > 4). In other words, (>5) is equivalent to \x -> x > 5.
In ((>) 5), (>) is the infix operator > converted to an expression. ((>) 5) then is the application of 5 to the function (>), which gives a new function that takes the next argument. If we apply that argument, e.g., (>) 5 4, we get the prefix equivalent of (5 > 4).
This conversion of an infix operator to an expression that can be used prefix works for all infix operators. You can also go the other way and covert an identifier into an infix operator, i.e.:
`foo`
You can even say:
(`foo`)
to turn it back into an expression.