For the following Haskell expression
return a >>= f
Should it be read as
(return a) >>= f
or
return (a >>= f)?
what are the related rules here?
The rule is always that function application has higher precedence than any operator, so
return a >>= f
Is parsed as
(return a) >>= f
no matter what functions or operators are being used instead of return, f, and >>=.
That means things like
divide :: Int -> Int -> Double
divide x y = (fromIntegral x) / (fromIntegral y)
Are equivalent to
divide :: Int -> Int -> Double
divide x y = fromIntegral x / fromIntegral y
Another example where this is even more useful is in function composition:
something :: [Int] -> [Int]
something xs = filter even . map (+1) . zipWith (*) [1..] . take 200 . cycle $ xs
As you can see here, we even have zipWith taking two arguments composed with several other functions. This is equivalent to having put parentheses around every component of the composition.
Related
I'm working my way through the Project Euler problems in Haskell. I have got a solution for Problem 3 below, I have tested it on small numbers and it works, however due to the brute force implementation by deriving all the primes numbers first it is exponentially slow for larger numbers.
-- Project Euler 3
module Main
where
import System.IO
import Data.List
main = do
hSetBuffering stdin LineBuffering
putStrLn "This program returns the prime factors of a given integer"
putStrLn "Please enter a number"
nums <- getPrimes
putStrLn "The prime factors are: "
print (sort nums)
getPrimes = do
userNum <- getLine
let n = read userNum :: Int
let xs = [2..n]
return $ getFactors n (primeGen xs)
--primeGen :: (Integral a) => [a] -> [a]
primeGen [] = []
primeGen (x:xs) =
if x >= 2
then x:primeGen (filter (\n->n`mod` x/=0) xs)
else 1:[2]
--getFactors
getFactors :: (Integral a) => a -> [a] -> [a]
getFactors n xs = [ x | x <- xs, n `mod` x == 0]
I have looked at the solution here and can see how it is optimised by the first guard in factor. What I dont understand is this:
primes = 2 : filter ((==1) . length . primeFactors) [3,5..]
Specifically the first argument of filter.
((==1) . length . primeFactors)
As primeFactors is itself a function I don't understand how it is used in this context. Could somebody explain what is happening here please?
If you were to open ghci on the command line and type
Prelude> :t filter
You would get an output of
filter :: (a -> Bool) -> [a] -> [a]
What this means is that filter takes 2 arguments.
(a -> Bool) is a function that takes a single input, and returns a Bool.
[a] is a list of any type, as longs as it is the same type from the first argument.
filter will loop over every element in the list of its second argument, and apply it to the function that is its first argument. If the first argument returns True, it is added to the resulting list.
Again, in ghci, if you were to type
Prelude> :t (((==1) . length . primeFactors))
You should get
(((==1) . length . primeFactors)) :: a -> Bool
(==1) is a partially applied function.
Prelude> :t (==)
(==) :: Eq a => a -> a -> Bool
Prelude> :t (==1)
(==1) :: (Eq a, Num a) => a -> Bool
It only needs to take a single argument instead of two.
Meaning that together, it will take a single argument, and return a Boolean.
The way it works is as follows.
primeFactors will take a single argument, and calculate the results, which is a [Int].
length will take this list, and calculate the length of the list, and return an Int
(==1) will
look to see if the values returned by length is equal to 1.
If the length of the list is 1, that means it is a prime number.
(.) :: (b -> c) -> (a -> b) -> a -> c is the composition function, so
f . g = \x -> f (g x)
We can chain more than two functions together with this operator
f . g . h === \x -> f (g (h x))
This is what is happening in the expression ((==1) . length . primeFactors).
The expression
filter ((==1) . length . primeFactors) [3,5..]
is filtering the list [3, 5..] using the function (==1) . length . primeFactors. This notation is usually called point free, not because it doesn't have . points, but because it doesn't have any explicit arguments (called "points" in some mathematical contexts).
The . is actually a function, and in particular it performs function composition. If you have two functions f and g, then f . g = \x -> f (g x), that's all there is to it! The precedence of this operator lets you chain together many functions quite smoothly, so if you have f . g . h, this is the same as \x -> f (g (h x)). When you have many functions to chain together, the composition operator is very useful.
So in this case, you have the functions (==1), length, and primeFactors being compose together. (==1) is a function through what is called operator sections, meaning that you provide an argument to one side of an operator, and it results in a function that takes one argument and applies it to the other side. Other examples and their equivalent lambda forms are
(+1) => \x -> x + 1
(==1) => \x -> x == 1
(++"world") => \x -> x ++ "world"
("hello"++) => \x -> "hello" ++ x
If you wanted, you could re-write this expression using a lambda:
(==1) . length . primeFactors => (\x0 -> x0 == 1) . length . primeFactors
=> (\x1 -> (\x0 -> x0 == 1) (length (primeFactors x1)))
Or a bit cleaner using the $ operator:
(\x1 -> (\x0 -> x0 == 1) $ length $ primeFactors x1)
But this is still a lot more "wordy" than simply
(==1) . length . primeFactors
One thing to keep in mind is the type signature for .:
(.) :: (b -> c) -> (a -> b) -> a -> c
But I think it looks better with some extra parentheses:
(.) :: (b -> c) -> (a -> b) -> (a -> c)
This makes it more clear that this function takes two other functions and returns a third one. Pay close attention the the order of the type variables in this function. The first argument to . is a function (b -> c), and the second is a function (a -> b). You can think of it as going right to left, rather than the left to right behavior that we're used to in most OOP languages (something like myObj.someProperty.getSomeList().length()). We can get this functionality by defining a new operator that has the reverse order of arguments. If we use the F# convention, our operator is called |>:
(|>) :: (a -> b) -> (b -> c) -> (a -> c)
(|>) = flip (.)
Then we could have written this as
filter (primeFactors |> length |> (==1)) [3, 5..]
And you can think of |> as an arrow "feeding" the result of one function into the next.
This simply means, keep only the odd numbers that have only one prime factor.
In other pseodo-code: filter(x -> length(primeFactors(x)) == 1) for any x in [3,5,..]
I've been investigating the usage of >>= with lists (when viewed as monads). In an article All about monads I found the following identity for lists: l >>= f = concatMap f l, where l is a list and f is some (unary) function. I tried the simple example of doubling each element of a list and arrived at the following:
let double :: Int -> [Int]
double = (flip (:) []) . (2*)
let monadicCombination :: [Int]
monadicCombination = [1,2,3,4,5] >>= double
I specifically wanted the double function to be written in a point-free manner. Can you think of simpler implementations of double so that it still can be used with >>=?
Sassa NF's return . (*2) is both short and demonstrates an interesting principle of your example. If we inline the whole thing we'll get
list >>= double
list >>= return . (*2)
The pattern \f l -> l >>= return . f Is common enough to have its own name: liftM
liftM :: Monad m => (a -> b) -> m a -> m b
liftM f m = m >>= return . f
And in fact, liftM is equivalent to fmap, often known as just map when referring to lists:
list >>= return . (*2)
liftM (*2) list
fmap (*2) list
map (*2) list
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)
I'm trying to understand what the dot operator is doing in this Haskell code:
sumEuler = sum . (map euler) . mkList
The entire source code is below.
My understanding
The dot operator is taking the two functions sum and the result of map euler and the result of mkList as the input.
But, sum isn't a function it is the argument of the function, right? So what is going on here?
Also, what is (map euler) doing?
Code
mkList :: Int -> [Int]
mkList n = [1..n-1]
euler :: Int -> Int
euler n = length (filter (relprime n) (mkList n))
sumEuler :: Int -> Int
sumEuler = sum . (map euler) . mkList
Put simply, . is function composition, just like in math:
f (g x) = (f . g) x
In your case, you are creating a new function, sumEuler that could also be defined like this:
sumEuler x = sum (map euler (mkList x))
The style in your example is called "point-free" style -- the arguments to the function are omitted. This makes for clearer code in many cases. (It can be hard to grok the first time you see it, but you will get used to it after a while. It is a common Haskell idiom.)
If you are still confused, it may help to relate . to something like a UNIX pipe. If f's output becomes g's input, whose output becomes h's input, you'd write that on the command-line like f < x | g | h. In Haskell, . works like the UNIX |, but "backwards" -- h . g . f $ x. I find this notation to be quite helpful when, say, processing a list. Instead of some unwieldy construction like map (\x -> x * 2 + 10) [1..10], you could just write (+10) . (*2) <$> [1..10]. (And, if you want to only apply that function to a single value; it's (+10) . (*2) $ 10. Consistent!)
The Haskell wiki has a good article with some more detail: http://www.haskell.org/haskellwiki/Pointfree
The . operator composes functions. For example,
a . b
Where a and b are functions is a new function that runs b on its arguments, then a on those results. Your code
sumEuler = sum . (map euler) . mkList
is exactly the same as:
sumEuler myArgument = sum (map euler (mkList myArgument))
but hopefully easier to read. The reason there are parens around map euler is because it makes it clearer that there are 3 functions being composed: sum, map euler and mkList - map euler is a single function.
sum is a function in the Haskell Prelude, not an argument to sumEuler. It has the type
Num a => [a] -> a
The function composition operator . has type
(b -> c) -> (a -> b) -> a -> c
So we have
euler :: Int -> Int
map :: (a -> b ) -> [a ] -> [b ]
(map euler) :: [Int] -> [Int]
mkList :: Int -> [Int]
(map euler) . mkList :: Int -> [Int]
sum :: Num a => [a ] -> a
sum . (map euler) . mkList :: Int -> Int
Note that Int is indeed an instance of the Num typeclass.
The . operator is used for function composition. Just like math, if you have to functions f(x) and g(x) f . g becomes f(g(x)).
map is a built-in function which applies a function to a list. By putting the function in parentheses the function is treated as an argument. A term for this is currying. You should look that up.
What is does is that it takes a function with say two arguments, it applies the argument euler. (map euler) right? and the result is a new function, which takes only one argument.
sum . (map euler) . mkList is basically a fancy way of putting all that together. I must say, my Haskell is a bit rusty but maybe you can put that last function together yourself?
Dot Operator in Haskell
I'm trying to understand what the dot operator is doing in this Haskell code:
sumEuler = sum . (map euler) . mkList
Short answer
Equivalent code without dots, that is just
sumEuler = \x -> sum ((map euler) (mkList x))
or without the lambda
sumEuler x = sum ((map euler) (mkList x))
because the dot (.) indicates function composition.
Longer answer
First, let's simplify the partial application of euler to map:
map_euler = map euler
sumEuler = sum . map_euler . mkList
Now we just have the dots. What is indicated by these dots?
From the source:
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)
Thus (.) is the compose operator.
Compose
In math, we might write the composition of functions, f(x) and g(x), that is, f(g(x)), as
(f ∘ g)(x)
which can be read "f composed with g".
So in Haskell, f ∘ g, or f composed with g, can be written:
f . g
Composition is associative, which means that f(g(h(x))), written with the composition operator, can leave out the parentheses without any ambiguity.
That is, since (f ∘ g) ∘ h is equivalent to f ∘ (g ∘ h), we can simply write f ∘ g ∘ h.
Circling back
Circling back to our earlier simplification, this:
sumEuler = sum . map_euler . mkList
just means that sumEuler is an unapplied composition of those functions:
sumEuler = \x -> sum (map_euler (mkList x))
The dot operator applies the function on the left (sum) to the output of the function on the right. In your case, you're chaining several functions together - you're passing the result of mkList to (map euler), and then passing the result of that to sum.
This site has a good introduction to several of the concepts.
I was trying to implement the function
every :: (a -> IO Bool) -> [a] -> IO Bool
which was the topic for this question. I tried to do this without explicit recursion. I came up with the following code
every f xs = liftM (all id) $ sequence $ map f xs
My function didn't work since it wasn't lazy (which was required in the question), so no upvotes there :-).
However, I did not stop there. I tried to make the function point-free so that it would be shorter (and perhaps even cooler). Since the arguments f and xs are the last ones in the expression I just dropped them:
every = liftM (all id) $ sequence $ map
But this did not work as expected, in fact it didn't work at all:
[1 of 1] Compiling Main ( stk.hs, interpreted )
stk.hs:53:42:
Couldn't match expected type `[m a]'
against inferred type `(a1 -> b) -> [a1] -> [b]'
In the second argument of `($)', namely `map'
In the second argument of `($)', namely `sequence $ map'
In the expression: liftM (all id) $ sequence $ map
Failed, modules loaded: none.
Why is that? I was under the impression that it was possible to simply drop trailing function arguments, which basically is what currying is about.
The definition of $ is
f $ x = f x
Let's fully parenthesize your function:
every f xs = (liftM (all id)) (sequence ((map f) xs))
and your curried version:
every = (liftM (all id)) (sequence map)
As you noticed, these are not identical. You can only drop trailing function arguments when they are the last thing applied. For example,
f x = g c x
is actually
f x = (g c) x
and the application of (g c) to x comes last, so you can write
f = g c
One pattern with the application operator $ is that it often becomes the composition operator . in points-free versions. This is because
f $ g $ x
is equivalent to
(f . g) $ x
For example,
every f xs = liftM (all id) $ sequence $ map f xs
can become
every f xs = (liftM (all id) . sequence . map f) xs
at which point you can drop xs:
every f = liftM (all id) . sequence . map f
Eliminating the argument f is more difficult, because it is applied before the composition operator. Let's use the definition of dot from http://www.haskell.org/haskellwiki/Pointfree:
dot = ((.) . (.))
With points, this is
(f `dot` g) x = f . g x
and is exactly what we need to make every fully points-free:
every = (liftM (all id) . sequence) `dot` map
Sadly, due to restrictions in the Haskell type system, this one needs an explicit type signature:
every :: (Monad m) => (a -> m Bool) -> [a] -> m Bool