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)
Related
With a simple Haskell adder function
addTwo:: Num a => a -> a -> a
addTwo a b = a + b
and following expressions
addTwo 4 5 -- yields 9
4 `addTwo` 5 -- yields 9
(`addTwo` 4) 5 -- yields 9
I understand the first two expressions. However, how does the third one work? Does the expression (`addTwo` 4) become a function of one argument? What is the general principle here?
Does the expression (`addTwo` 4) become a function of one argument?
Yes, this is exactly what happens. This is exactly the same as any other operator section like (+4), just using backticks instead of some other infix operator. In general, (a `op`) is the same as \x -> a `op` x, while (`op` a) is the same as \x -> x `op` a.
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 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)).
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.
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.