How to use the ($) operator correctly - haskell

These lines execute correctly:
Prelude> 1 / (1 + 1)
0.5
Prelude> (/) 1 $ (+) 1 1
0.5
Prelude> (/) 1 $ 1 + 1
0.5
This one does not:
Prelude> 1 / $ (+) 1 1
<interactive>:1:4: parse error on input `$'
Why?

/ is an infix operator. It requires valid expression on both its sides. 1 is a literal and thus a valid expression. However, on right-hand side you have immediately another infix operator, which requires to be preceded by another valid expression (and 1 / is not a valid expression, as it lacks right-hand side argument to the / operator). This is why parser reports error (invalid grammar — see haskell report for ugly details ;)

I believe that it is because $ is an operator that requires a function preceding it. The expression 1 / in your last example does not evaluate to a function. In that case, the parser is expecting to find a (numeric) expression as the second argument to the / operator.

Related

Haskell: Understanding function application operator when used with map function

I have the following Haskell expression:
map ($ 5) [(-),(+),(*)]
I know the function application operator ($) applies a function to a given parameter. However since the (-), (+) and (*) functions take two parameters, by applying these functions to 5 through map, the functions are partially applied.
The resulting list will contain three functions that takes another parameter and:
(1) Subtracts the parameter from 5
(2) Adds the parameter to 5
(3) Multiplies the parameter by 5
However is it valid to say that the above expression is equivalent to the following?
[(5 -),(5 +),(5 *)]
I think this is correct, since I checked the types of (5 -), (5 +) and (5 *) in GHCI, and they are all functions that take a number and return a number:
(5 -) :: Num a => a -> a
(5 +) :: Num a => a -> a
(5 *) :: Num a => a -> a
Any insights are appreciated.
Correct; you can also apply the operators a second time via:
map ($4) $ map ($ 5) [(-),(+),(*)]
producing [5-4, 5 + 4, 5 * 4]
Also, you can specify the arguments to the right of the operator, giving the same result:
[((-) 5),(+ 5),(* 5)]
(The reason the (-) 5 has the "-" parenthesized, is to prevent the compiler to think you mean "minus five", a negative number, the usual interpretation of (- 5)).

What does the 'outermost part' of expression mean in Haskell

True beginner here, and I'm reading about the differences between NF and WHNF, and one of the definitions I come across states
To determine whether an expression is in weak head normal form, we only have to
look at the outermost part of the expression.
I'm not sure what criteria to apply to determine what the 'outermost' part is. For example (from a stack overflow answer by #hammer):
'h' : ("e" ++ "llo") -- the outermost part is the data constructor (:)
(1 + 1, 2 + 2) -- the outermost part is the data constructor (,)
\x -> 2 + 2 -- the outermost part is a lambda abstraction
Especially in the first example there, the (:) operator is in the middle of the 'h' and the other expression, so how is it the outermost part?
In general, when looking at an expression, how does one determine what the outermost part is?
Good question. Here, "outermost" (or "topmost") describes the location in reference to a kind of standard, abstract view of the expression that can differ from its actual syntax. For example, these two expressions:
(1, 2)
(,) 1 2
have identical meaning in Haskell. It turns out that in both cases, the constructor (,) is the outermost part of the expression, even though the expressions have different syntactic form with the comma appearing in different physical locations in the syntax.
Generally speaking, Haskell's "standard syntax" involves function application of the form:
fexpr expr1 .. exprn
However, the language also allows other kinds of syntax:
1 + 2 -- infix operators
(3, 4) -- tuples
[5,6,7,8] -- lists
"abc" -- strings
These alternate syntaxes can be converted to the standard syntax like so:
1 + 2 ==> (+) 1 2
(3, 4) ==> (,) 3 4
[5,6,7,8] ==> (:) 5 ((:) 6 ((:) 7 ((:) 8 [])))
"abc" ==> (:) 'a' ((:) 'b' ((:) 'c' []))
Though it's far from obvious, (+) is a variable whose value is a function (like sqrt); while (,) and (:) are constructors (just like True or Just). Even more confusing and further from obvious, even though [1,2,3] is special syntax, the empty list [] is a (unary) constructor! That's why I still used empty lists on the right-hand side in my standard syntax versions.
Anyway, once converted to the standard syntax, an expression will either be a constructor application, like one of these:
True -- a nullary constructor
(,) (1+2) (2+3) -- constructor expecting two args and fully applied
(:) 5 -- constructor partially applied and expecting one more arg
and we say that the "outermost part" of the expression is this constructor application, or it will be an unapplied lambda abstraction:
(\x y -> (+) x (length y))
and we say that the "outermost part" of the expression is this unapplied lambda abstraction, or it will be something else:
w -- a variable
(\x -> x) 10 -- an applied lambda abstraction
(f x) y ((*) 2 z) -- some other function application
(+) 10 (length (1:[])) -- another function application
and we say the "outermost part" of the expression is a variable reference or a function application or whatever.
Anyway, if the outermost part is either a constructor application or an unapplied lambda abstraction, then it's said to be in weak head normal form. If it's something else, it's not.
So, Just (5+6) is in WHNF because the outermost part is the application of the constructor Just. On the other hand, sqrt (5+6) is not in WHNF because the outermost part is the application of the variable sqrt, and a variable isn't a constructor.
Similarly, 5+6 itself is not in WHNF because the outermost part is the application of the variable (+) to 5 and 6, while [5,6] is in WHNF because the outermost part is the application of the (implied) constructor (:) to 5 and [6].
You have to look at the abstract syntax tree to understand what this means.
:
/ \
'h' ++
/ \
"e" "llo"
(,)
/ \
+ +
/ \ / \
1 1 2 2
\x ->
|
+
/ \
2 2
"Outermost" means the root of the tree.

Fixity of infix value constructors

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)

Infix function evaluation with $

$ is an infix operator with the lowest possible precedence:
f $ a = f a
Does this not mean that, in the expression below, the part
$ 2 ^ 2
should be evaluated first and then add $ 2? It appears 2 + 2 is evaluated first
Prelude> (2^) $ 2 + 2
returns :
16
No. Try to think of precedence not as being about what gets "evaluated first", and more about where parentheses are inserted.
The fact that $ has the lowest precedence means that parentheses are inserted around everything to the right of it (and, separately, to the left of it, if needed, but they aren't needed here). So
(2^) $ 2 + 2
is equivalent to
(2^) $ (2 + 2)
which is of course
(2^) 4 (i.e. 16)
Precedence rules can be confusing, but I like to think of it as "lower precedence" means "do later". Since $ has the lowest precedence (for example, below (+)), it is performed after (+). Thus (2^) $ 2 + 2 evaluates (2^) to a partially applied function, then evaluates 2+2 to 4, then applies 4 to 2^ to get 16.

What is the difference between an operator and a function in Haskell?

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.

Resources