Why does the dot compose from right to left in Haskell? - haskell

If we have two functions, f and g, then in Haskell h = f . g is equivalent to h x = f(g x). I.e. the functions are applied from right to left to the input. Is there any fundamental reason why it goes from right to left, and not from left to right? I.e. why didn't they make h = f . g equivalent to h x = g(f x) instead?
EDIT: as others pointed out my equivalent functions where the wrong way around, so I fixed those.

First of all, there's a mistake in your [original, unedited] question:
h = f . g is equivalent to h x = g(f x)
— that's not true: h = f . g is equivalent to h x = f (g x).
However, as to why it's that way and not the other way around, it's most likely because that's how it works and has worked in math; see http://en.wikipedia.org/wiki/Function_composition:
[...] composite function is denoted g ∘ f : X → Z, defined by (g ∘ f )(x) = g(f(x)) for all x in X.
It's also intuitive because of the equality (f . g) x == f (g x) — as you can see, the order of f and g is the same on both sides.
Moreover, it's trivial to create your own "reverse composition" operator if you desire one for reasons of e.g. readability:
(.>) = flip (.)
so that
Prelude> ((+1) .> (*2)) 3
8
Prelude> ((+1) . (*2)) 3
7
In fact, you can just use Control.Arrow.(>>>) which does the same for functions but is more general and works for other things as well:
Prelude Control.Arrow> ((+1) >>> (*2)) 3
8

Related

Dot in haskell, tricky example

I know that "haskells dot" question was answered couple times before on stackoverflow but I came across a example that shows me I still don't fully get it. Let's say I have functions
f :: Integer -> Integer
f x = x
g x = \y -> y
Now, as far as I know dot works like function composition -> f (g x) = (f . g) x
. So
(f . g) 4 5
shuld returns 5. Because g takes two arguments and returns second one, and f is simply identity. However it doesn't, Im getting Couldn't match type error. I have a feeling that haskell parses this expresion to something like ((f . g) 4) 5. But I need deeper explanation
As mentioned in the question, we have:
(f . g) x = f (g x)
Hence, in particular
(f . g) 4 = f (g 4) (*)
from which we have
(f . g) 4 5
= -- application associates to the left
((f . g) 4) 5
= -- equation (*) above
(f (g 4)) 5 =
= -- application associates to the left
f (g 4) 5
We can now see that the last argument 5 is being left as the second argument of f, and not passed to g.
It is useful to remember that Haskell functions are curried: technically, there's no such a thing as a function which takes two arguments. A function having type a -> b -> c is actually a unary function returning a unary function, even if we like to think of that as a binary function.
The composition operator works on unary functions as well: f . g composes the unary functions f and g. If f is "binary", it is treated as a unary function returning a function. This makes it take an additional argument, as shown above. If g is "binary", its returned function is passed to f.
So, using the above definitions:
f x = x
g x = \y -> y
we get:
(f . g) 4 5
= -- done above
f (g 4) 5
= -- associativity
(f (g 4)) 5
= -- definition of f
(g 4) 5
= -- definition of g
(\y -> y) 5
= -- beta reduction
5
main = print $(f . g) 4 5
f x = x
g x = \y -> y
Compiles nicely and when run prints 5. I'm using GHC 8.0.1.
Maybe you'd rather provide a complete minimal etc. example?

Transforming a List of 2-Tuples in Haskell

(Background: Trying to learn Haskell, very new to functional programming. Typically used to Python.)
Suppose I have a list of 2-tuples, a histogram:
let h = [(1,2),(3,5),(4,6),(5,3),(6,7),(7,4),(8,6),(9,1)]
In imperative terms, I want to change the second term of each pair to be the sum of all the previous second pairs. In Python, the following (admittedly complex) list comprehension could do it:
[(p[0], sum( [p[1] for p in histogram[:i+1]] ))
for i, p in enumerate(histogram)]
assuming histogram refers to a list of 2-tuples like h above.
Here's what I have so far in Haskell:
zip [fst p | p <- h] (scanl1 (+) [snd k | k <- h])
This works, but I wonder:
Is this reading through the list once, or twice?
Can it be expressed better? (I expect so.)
In case it isn't clear, this is the expected output for the above:
[(1,2),(3,7),(4,13),(5,16),(6,23),(7,27),(8,33),(9,34)]
You could use this function
accumulate = scanl1 step
where step (_,acc) (p1,p2) = (p1,acc+p2)
Here is the result on your sample data:
*Main> accumulate h
[(1,2),(3,7),(4,13),(5,16),(6,23),(7,27),(8,33),(9,34)]
If you're new to Haskell this might be a little too early, but lens offers a nice succinct way:
> scanl1Of (traverse . _2) (+) h
[(1,2),(3,7),(4,13),(5,16),(6,23),(7,27),(8,33),(9,34)]
You can easily accumulate only the first one by switching to _1:
> scanl1Of (traverse . _1) (+) h
[(1,2),(4,5),(8,6),(13,3),(19,7),(26,4),(34,6),(43,1)]
Or accumulate all values as a sort of nested list:
> scanl1Of (traverse . both) (+) h
[(1,3),(6,11),(15,21),(26,29),(35,42),(49,53),(61,67),(76,77)]
Well,... (,) is a Data.Bifunctor and Data.Biapplicative
scanl1 (biliftA2 (flip const) (+))
is what you want.
A Functor is such a type f that for any a can apply any function a->b to f a to get f b. For example, (a,) is a Functor: there is a way to apply any function b->c to translate (a,b) to (a,c).
fmap f (x,y) = (x,f y)
A Bifunctor is such a type f that for any a and b can apply two functions a->c and b->d to f a b to get f c d. For example, (,) is a Bifunctor: there is a way to apply any pair of functions a->c and b->d to translate (a,b) into (c,d).
bimap f g (x,y) = (f x, g y)
A Biapplicative is such a type f that for any a and b can apply f (a->c) (b->d) to f a b to get f c d. For example, (,) is a Biapplicative: there is a way to apply any functions in the pair to translate (a,b) into (c,d)
biap (f,g) (x,y) = (f x, g y)
Data.Biapplicative defines biliftA2 to "lift" a pair of functions a->c->e and b->d->f - constructs a function of two arguments of type (a,b) and (c,d)
biliftA2 f g = \(x,y) (z,t) -> (f x z, g y t)
So biliftA2 constructs a function that can be used in scanl1 to do the necessary folding. flip const will ignore the first projection of the previous pair, and (+) will add up the second projection of the previous and next pair.

Applying multiple functions to the same value point-free style in Haskell

I was bored one day and wanted to exercise my brain, so I decided to do the 99 Haskell Problems but restricted myself to doing them in point-free style. A problem that seems to crop up a lot when I'm doing things in point-free style is this: How do you apply multiple functions to the same value while keeping each result as an independent entity? Using pointed notation:
foobar x = [id x, reverse x]
And what I've come up with so far in point-free notation:
foobar' = `map` [id, reverse] ($ x)
I can't seem to get that x off the end of there.
Others have already posted how you can do this using the Reader monad, but that's not the only way. It turns out that your second function is pretty close. I think you meant to post
foobar' x = (`map` [id, reverse]) ($ x)
Since the x is already near a rightmost position, you're almost there. First, transform the section ($ x) into a function, because it's a bit easier to work with:
-- by the definition of a right operator section
foobar'2 x = (`map` [id, reverse]) (\y -> ($) y x)
Next remove the x from the lambda body by bringing a new variable into scope, and applying the function to x
-- lambda abstraction I think...
foobar'2 x = (`map` [id, reverse]) $ (\z y -> ($) y z) x
Rewrite this application as a function composition, and then you can eta reduce:
-- by definition of '.'
foobar'3 x = (`map` [id, reverse]) . (\z y -> ($) y z) $ x
-- eta reduction
foobar'4 = (`map` [id, reverse]) . (\z y -> ($) y z)
Finally, notice that we can replace the lambda with a function
-- by definition of `flip`
foobar'5 = (`map` [id,reverse]) . flip ($)
and you have a point-free form.
You will be interested in the Applicative instance of the reader monad:
instance Applicative (e ->)
Using it you can easily distribute an argument:
liftA2 (+) sin cos 3
Here sin and cos are functions, which both receive the value 3. The individual results are then combined using (+). You can further combine this with the Category instance of (->), but of cource specialized versions of (.) and id are already defined in the Prelude.
Background: The Applicative instance for (e ->) really represents the SKI calculus, where (<*>) is the S combinator and pure is the K combinator. S is precisely used to distribute an argument to two functions:
S f g x = f x (g x)
It takes a function application (f g) and makes both dependent on the value x ((f x) (g x)).
Use sequence:
> let foobar' = sequence [id, reverse]
> foobar' "abcde"
["abcde","edcba"]
There are a few basic idiomatic combinators which pop up repeatedly, and are reimplemented with various higher concepts and libraries, but which are essentially very simple. Names may vary, and some are implementable in terms of others:
fork (f,g) x = (f x, g x) -- == (f &&& g)
prod (f,g) x = (f $ fst x, g $ snd x) -- == (f *** g)
pmap f (x,y) = (f x, f y) -- == (f *** f)
dup x = (x,x)
etc. Of course uncurry f (x,y) == f x y gets used a lot with these, too.
&&& and *** are defined in Control.Arrow, as well as first and second. Then prod (f,id) == first f, prod(id,g) == second g etc. etc.
So your foobar becomes
foobar = (\(a,b)->[a,b]) . fork (id,reverse)
= (\(a,b)->[a,b]) . (id &&& reverse)
= (\(a,b)->[a,b]) . (id *** reverse) . dup
= join $ curry ( (\(a,b)->[a,b]) . second reverse)
For the last one you need to also import Control.Monad and Control.Monad.Instances. See also this question.
late edit: also, using Control.Applicative as hinted in answer by ertes,
= (:) <*> ((:[]) . reverse)

simple Haskell functions in point-free style

I am trying to understand how to convert functions to point-free notation in Haskell. I saw this example, but it is more complicated than what I am looking for. I feel like I understand the logic behind it, but when I am trying to execute some simple examples in code I am getting compile errors. I want to try and write this function in point-free style:
f x = 5 + 8/x which I rearranged as f x = (+) 5 $ (/) 8 x
So, I thought it might be something like this:
f = (+) 5 $ (/) 8
but when I run this in ghci I get this message:
No instance for (Num (a0 -> a0))
arising from the literal `5' at Test.hs:3:9
Possible fix: add an instance declaration for (Num (a0 -> a0))
In the first argument of `(+)', namely `5'
In the first argument of `($)', namely `(+) 5'
In the expression: (+) 5 $ (/) 8
Failed, modules loaded: none.
I don't understand the "No instance for..." message. What do I need to do to write this function in point-free style?
$ has a very low precedence. So, f x = (+) 5 $ (/) 8 x actually means f x = (+) 5 $ ((/) 8 x). Instead, rewrite that as
f x = (+) 5 ( (/) 8 x)
f x = ((+) 5) ( ((/) 8) x)
f x = ((+) 5) . ( ((/) 8) ) x
f = ((+) 5) . ( (/) 8 )
f = (5+) . (8/)
The last expression makes sense: f is the composition of two operations, first divide 8 by what one has, and then add 5 to the result. Remember, g.h means "apply h, then apply g the the result of that".
Conversion from lambda-calculus (which Haskell is a variant of) terms to SKI terms (totally pointfree functions, using only const (K), id (I) and <*> (S)) can be done with the following simple rules:
\x -> x translates to id;
\x -> y without x occurring in y translates to const y;
\x -> f g translates to f' <*> g' where
f' is a translation of \x -> f and
g' is a translation of \x -> g.
Now you may wonder where does the . come in. There is a special case of the last translation: if f does not have any free occurrences of x, then \x -> f g translates to const f <*> (\x -> g), which is equal to f . (\x -> g).
Using those rules we can convert your function:
f = \x -> ((+) 5) (((/) 8) x) = -- by the special-case (.) rule
((+) 5) . (\x -> (((/) 8) x)) = -- by eta-reduction ((\x -> f x) = f)
((+) 5) . ((/) 8)
Eta-reduction is not necessary to complete the translation, but without it we'd get something messier. For example, the last step would yield ((+) 5) . ((/) 8) . id instead.
The "pointfree" program can be installed with cabal install pointfree, and shows you how to write an expression in pointfree style. For example:
$ pointfree "f x = 5 + 8/x"
f = (5 +) . (8 /)
Explanation of this conversion:
You can use "sections" for infix/operator functions. (a +) == \b -> a + b and (+ a) == \b -> b + a
The . function takes the result of the second parameter, which is a one-argument function, and applies it to the first argument.
You were really close. Allow me to add one more $ to illustrate:
f x = (+) 5 $ (/) 8 $ x
It should be clear that the expression (+) 5 is a function that takes one numeric input and produces a numeric output. The same goes for the expression (/) 8. So you take whatever number is input, x, and first apply the (/) 8 "function", and then apply the (+) 5 "function".
Whenever you have a chain of functions separated by $, you can replace all except the rightmost with . Meaning, if you have a $ b $ c $ d, this is equivalent to a . b . c $ d.
f x = (+) 5 . (/) 8 $ x
At this point, let's actually remove the $ and parenthesize instead.
f x = ((+) 5 . (/) 8) x
Now it should be clear that you can remove the trailing x from both sides:
f = (+) 5 . (/) 8
That is the main idea. If you have f x = expr x, you can "eta reduce" it to f = expr. In order to produce pointfree code, you need simply recognize how the larger function is composed of smaller functions. Partial application is sometimes necessary for point free code (as in this case, (+) 5 and (/) 8 are partially applied). The "pointfree" program is quite helpful for when you don't want to think about it; Lambdabot on the #haskell irc channel uses this program as a plugin, so you don't even have to install it yourself; just ask:
<DanBurton> #pl let f x = 5 + 8 / x in f
<lambdabot> (5 +) . (8 /)

What does a fullstop or period or dot (.) mean in Haskell?

I really wish that Google was better at searching for syntax:
decades :: (RealFrac a) => a -> a -> [a] -> Array Int Int
decades a b = hist (0,9) . map decade
where decade x = floor ((x - a) * s)
s = 10 / (b - a)
f(g(x))
is
in mathematics : f ∘ g (x)
in haskell : ( f . g ) (x)
It means function composition.
See this question.
Note also the f.g.h x is not equivalent to (f.g.h) x, because it is interpreted as f.g.(h x) which won't typecheck unless (h x) returns a function.
This is where the $ operator can come in handy: f.g.h $ x turns x from being a parameter to h to being a parameter to the whole expression. And so it becomes equivalent to f(g(h x)) and the pipe works again.
. is a higher order function for function composition.
Prelude> :type (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
Prelude> (*2) . (+1) $ 1
4
Prelude> ((*2) . (+1)) 1
4
"The period is a function composition operator. In general terms, where f and g are functions, (f . g) x means the same as f (g x). In other words, the period is used to take the result from the function on the right, feed it as a parameter to the function on the left, and return a new function that represents this computation."
It is a function composition: link
Function composition (the page is pretty long, use search)

Resources