Why is (.) called infix as just . rather than `(.)` - haskell

I learned that functions can be invoked in two ways; prefix and infix. For example, say I've created this function:
example :: [Char] -> [Char] -> [Char]
example x y = x ++ " " ++ y
I can call it prefix like so:
example "Hello" "World"
or infix like so:
"Hello" `example` "World"
Both of which will result in the list of chars representing a string "Hello World".
However, I am now learning about function composition, and have come across the function defined like so:
(.) :: (b -> c) -> (a -> b) -> a -> c
So, say I was wanting to compose negate with multiplication by three. I would write the prefix invocation like:
negateComposedWithMultByThree = (.) negate (*3)
And the infix invocation like:
negateComposedWithMultByThree = negate `(.)` (*3)
But, whilst the prefix invocation compiles, the infix invocation does not and instead gives me the error message:
error: parse error on input `('
It seems, in order to call compose infix, I need to omit the brackets and call it like so:
negateComposedWithMultByThree = negate . (*3)
Can anyone shed any light on this? Why does "Hello" `example` "World" whilst negate `(.)` (*3) does not?
In addition, if I try to make my own function with a signature like this:
(,) :: Int -> Int
(,) x = 1
It does not compile, with the error:
"Invalid type signature (,) : ... Should be of form :: "

There's nothing deep here. There's just two kinds of identifiers that have different rules about how they're parsed: by-default-infix, and by-default-prefix. You can tell which is which, because by-default-infix identifiers contain only punctuation, while by-default-prefix identifiers contain only numbers, letters, apostrophes, and underscores.
Recognizing that the default isn't always the right choice, the language provides conversions away from the default behavior. So there are two separate syntax rules, one that converts a by-default-infix identifier to prefix (add parentheses), and one that converts a by-default-prefix identifier to infix (add backticks). You can not nest these conversions: a by-default-infix identifier converted to prefix form is not a by-default-prefix identifier.
That's it. Nothing fundamentally interesting -- all of them become just function applications once parsed -- it's just syntax sugar.

Related

Is whitespace either used as a function application operator or a word separator

How does outermost evaluation work on an application of a curried function? says:
in Haskell, whitespace is an operator: it applies the lhs function to the rhs argument.
Is it true? I can't find it in documents.
When Haskell compiler lexical analyzing a Haskell program, is a whitespace recognized as either a function application operator or a token separator?
I’ve never heard anyone say that whitespace is an operator before. I suppose you could consider it to be an operator in the context of a function application, but in most contexts it is not an operator. For instance, I don’t see any way to consider whitespace as an operator in the following code sample, where whitespace is used only to separate tokens:
module Main where
x = "test 1"
y = "test 2"
main = do
(z : zs) <- getLine
putStrLn $ z : (x ++ y ++ zs)
It seems fairly obvious here that whitespace is acting purely as a token separator. The apparent ‘operator-ness’ in something like f x y z can be best thought of as saying that if two values are placed next to each other, the second is applied to the first. For instance, putStrLn"xxx" and putStrLn "xxx" both apply "xxx" to putStrLn; the space is completely irrelevant.
EDIT: In a comment, #DanielWagner provided two great examples. Firstly, (f)x is the same as f x, yet has no whitespace; here we see confirmation that the space is acting purely as a token separator, so can be replaced by a bracket (which also separates tokens) without any impact on the lexemes of the expression. Secondly, f {x=y} does not apply {x=y} to f, but rather uses record syntax to create a new record based on f; again, we can remove the space to get f{x=y}, which does an equally good job of separating the lexemes.
The white space in most cases is "function application", meaning apply the function of the right, to the argument to the left, just like the ($) operator, but it can be used to be more clear on your code, some examples:
plusOne = (1 +)
you can either do
plusOne 2
or
plusOne $ 2
:t ($)
($) :: (a -> b) -> a -> b
I forgot a usefull example:
imagine you want to filter the greater than 3, but before you want to add one to each element:
filter (>3) $ map plusOne [1,2,3,4]
That will compile, but this wont:
filter (>3) map plusOne [1,2,3,4]
But in other cases, is not function application, like the other #bradrn answer or #Daniel warner comment just shows.

Strange tilde syntax

GHC accepts this code, but it ought to be illegal syntax(?) Any guesses as to what's going on?
module Tilde where
~ x = x + 2 -- huh?
~ x +++ y = y * 3 -- this makes sense
The (+++) equation makes sense: it's declaring an operator, using infix syntax, and using an irrefutable pattern match on the first argument.
The first 'equation' looks like the same to start with. But there's no operator. If I ask
λ> :i ~
===> <interactive>:1:1: error: parse error on input `~'
λ> :i (~)
===> class (a ~ b) => (~) (a :: k) (b :: k)
-- Defined in `Data.Type.Equality'
instance [incoherent] forall k (a :: k) (b :: k). (a ~ b) => a ~ b
-- Defined in `Data.Type.Equality'
which is a bemusing discovery, but nothing to do with it(?) I can't define my own class or operator (~) -- Illegal binding of built-in syntax, not surprisingly.
Oh:
λ> :i x
===> x :: Integer -- GHCi defaulting, presumably
and trying to run x loops for ever. So the strangeness is actually defining
x = x + 2
Then what's the ~ doing?
The tilde is doing exactly what it did in your other example: it makes the pattern irrefutable (so the pattern match can not fail). The pattern already was irrefutable, of course, in both cases (being a plain variable, which always matches), but that doesn't make the tilde illegal, just unnecessary.
Writing
x = 5
creates a global variable named x, bound to the value 5. Adding a tilde makes the pattern match irrefutable, but it was already irrefutable, so that doesn't make much sense. But it's legal to write something like
(xs, ys) = span odd [1..10]
This defines two global variables, xs and ys, containing all the odd numbers and all the even numbers between 1 and 10. You could even make this irrefutable if you want by adding a tilde. Of course, this pattern can't fail (if the expression is well-typed), so there's no point to that. But consider:
~(x:xs) = filter odd [1..10]
This defines two global variables, x and xs, if the filter returns at least one result. If the filter were to return zero results, the pattern match would fail. (In practice, this means that accessing x or xs would throw a pattern match failure exception.)
You can even write utterly bizarre stuff like
False = True
This seemingly nonsensical declaration pattern-matches the pattern False against the value True, and does nothing either way. It's one of those obscure corners of the language.

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.

printing a list of type signatures

I want to be able to type the following in ghci:
map showTypeSignature [(+),(-),show]
I want ghci to return the following list of Strings:
["(+) :: Num a => a -> a -> a","(-) :: Num a => a -> a -> a","show :: Show a => a -> String"]
Naturally, the first place that I run into trouble is that I cannot construct the first list, as the type signatures of the functions don't match. What can I do to construct such a list? How does ghci accomplish the printing of type signatures? Where is the ghci command :t defined (its source)?
What you're asking for isn't really possible. You cannot easily determine the type signature of a Haskell term from within Haskell. At run-time, there's hardly any type information available. The GHCi command :t is a GHCi command, not an interpreted Haskell function, for a reason.
To do something that comes close to what you want you'll have to use GHC itself, as a library. GHC offers the GHC API for such purposes. But then you'll not be able to use arbitrary Haskell terms, but will have to start with a String representation of your terms. Also, invoking the compiler at run-time will necessarily produce an IO output.
kosmikus is right, this doesn't really work out. And shouldn't, the static type system is one of Haskell's most distinguishing features!
However, you can emulate this for monomorphic functions quite well using the Dynamic existential:
showTypeSignature :: Dynamic -> String
showTypeSignature = show . dynTypeRep
Prelude Data.Dynamic> map showTypeSignature [toDyn (+), toDyn (-), toDyn (show)]
["Integer -> Integer -> Integer","Integer -> Integer -> Integer","() -> [Char]"]
As you see ghci had to boil the functions down to monomorphic type here for this to work, which particularly for show is patently useless.
The answers you have about why you can't do this are very good, but there may be another option. If you don't care about getting a Haskell list, and just want to see the types of a bunch of things, you can define a custom GHCi command, say :ts, that shows you the types of a list of things; to wit,
Prelude> :ts (+) (-) show
(+) :: Num a => a -> a -> a
(-) :: Num a => a -> a -> a
show :: Show a => a -> String
To do this, we use :def; :def NAME EXPR, where NAME is an identifier and EXPR is a Haskell expression of type String -> IO String, defines the GHCi command :NAME. Running :NAME ARGS evaluates EXPR ARGS to produce a string, and then runs the resulting string in GHCi. This is less confusing than it sounds. Here's what we do:
Prelude> :def ts return . unlines . map (":type " ++) . words
Prelude> :ts (+) (-) show
(+) :: Num a => a -> a -> a
(-) :: Num a => a -> a -> a
show :: Show a => a -> String
What's going on? This defines :ts to evaluate return . unlines . map (":t " ++) . words, which does the following:
words: Takes a string and splits it on whitespace; e.g., "(+) (-) show" becomes ["(+)", "(-)", "show"].
map (":type " ++): Takes each of the words from before and prepends ":type "; e.g., ["(+)", "(-)", "show"] becomes [":type (+)", ":type (-)", ":type show"]. Notice that we now have a list of GHCi commands.
unlines: Takes a list of strings and puts newlines after each one; e.g., [":type (+)", ":type (-)", ":type show"] becomes ":type (+)\n:type (-)\n:type show\n". Notice that if we pasted this string into GHCi, it would produce the type signatures we want.
return: Lifts a String to an IO String, because that's the type we need.
Thus, :ts name₁ name₂ ... nameₙ will evaluate :type name₁, :type name₂, …, :type nameₙ in succession and prints out the results. Again, you can't get a real list this way, but if you just want to see the types, this will work.

When should I use $ (and can it always be replaced with parentheses)?

From what I'm reading, $ is described as "applies a function to its arguments." However, it doesn't seem to work quite like (apply ...) in Lisp, because it's a binary operator, so really the only thing it looks like it does is help to avoid parentheses sometimes, like foo $ bar quux instead of foo (bar quux). Am I understanding it right? Is the latter form considered "bad style"?
$ is preferred to parentheses when the distance between the opening and closing parens would otherwise be greater than good readability warrants, or if you have several layers of nested parentheses.
For example
i (h (g (f x)))
can be rewritten
i $ h $ g $ f x
In other words, it represents right-associative function application. This is useful because ordinary function application associates to the left, i.e. the following
i h g f x
...can be rewritten as follows
(((i h) g) f) x
Other handy uses of the ($) function include zipping a list with it:
zipWith ($) fs xs
This applies each function in a list of functions fs to a corresponding argument in the list xs, and collects the results in a list. Contrast with sequence fs x which applies a list of functions fs to a single argument x and collects the results; and fs <*> xs which applies each function in the list fs to every element of the list xs.
You're mostly understanding it right---that is, about 99% of the use of $ is to help avoid parentheses, and yes, it does appear to be preferred to parentheses in most cases.
Note, though:
> :t ($)
($) :: (a -> b) -> a -> b
That is, $ is a function; as such, it can be passed to functions, composed with, and anything else you want to do with it. I think I've seen it used by people screwing with combinators before.
The documentation of ($) answers your question. Unfortunately it isn't listed in the automatically generated documentation of the Prelude.
However it is listed in the sourcecode which you can find here:
http://darcs.haskell.org/packages/base/Prelude.hs
However this module doesn't define ($) directly. The following, which is imported by the former, does:
http://darcs.haskell.org/packages/base/GHC/Base.lhs
I included the relevant code below:
infixr 0 $
...
-- | Application operator. This operator is redundant, since ordinary
-- application #(f x)# means the same as #(f '$' x)#. However, '$' has
-- low, right-associative binding precedence, so it sometimes allows
-- parentheses to be omitted; for example:
--
-- > f $ g $ h x = f (g (h x))
--
-- It is also useful in higher-order situations, such as #'map' ('$' 0) xs#,
-- or #'Data.List.zipWith' ('$') fs xs#.
{-# INLINE ($) #-}
($) :: (a -> b) -> a -> b
f $ x = f x
Lots of good answers above, but one omission:
$ cannot always be replace by parentheses
But any application of $ can be eliminated by using parentheses, and any use of ($) can be replaced by id, since $ is a specialization of the identity function. Uses of (f$) can be replaced by f, but a use like ($x) (take a function as argument and apply it to x) don't have any obvious replacement that I see.
If I look at your question and the answers here, Apocalisp and you are both right:
$ is preferred to parentheses under certain circumstances (see his answer)
foo (bar quux) is certainly not bad style!
Also, please check out difference between . (dot) and $ (dollar sign), another SO question very much related to yours.

Resources