I have a simple function, and the desire to make sense of point-free style.
shout :: String -> String
shout input
| null input = []
| otherwise = (toUpper . head $ input) : (shout . tail $ input)
My intuition led me to this
pfShout :: String -> String
pfShout = (toUpper . head) : (shout . tail)
which is complaining about the following for the first argument of the cons cell
Couldn't match expected type 'String -> String'
with actual type '[[Char] -> Char]'
Possible cause: '(:)' is applied to too many arguments
In the expression: (toUpper . head) : (pfShout . tail)
In an equation for 'pfShout':
pfShout = (toUpper . head) : (pfShout . tail)
and complaining about this for the second argument of the cons cell
Couldn't match expected type '[[Char] -> Char]'
with actual type '[Char] -> String'
Probable cause: '(.)' is applied to too few arguments
In the second argument of '(:)', namely '(pfShout . tail)'
In the expression: (toUpper . head) : (pfShout . tail)
In an equation for 'pfShout':
pfShout = (toUpper . head) : (pfShout . tail)
It's clear to me that I can't make a list out of 'String -> String' functions and '[[Char]->Char]', and I'm starting to get a to a place where I'm thinking this just isn't gonna work point-free.
I understand there are other considerations here (like now I'm missing a base-case), but . I also understand I could completely re-write the function to achieve the same effect (like map toUpper). I'm primarily interested in point-free using recursion with the function as it is written.
If it is (or isn't) possible to write this function point-free, what am I missing?
As #n.m noted you can use shout = map toUpper. However it is possible to do this without map or any other fancy functions like foldr, but we need more combinators. We need something that takes our input argument and passes it to two functions toUpper . head and shout . tail and then combines them with :. You propably don't know this function yet, but the <*> operator from applicative has what we need:
(f <*> g) x = f x (g x)
Now we can do something like this:
combine . f <*> g = \x -> combine (f x) (g x) -- [1]
I will let you figure out how exactly to apply this to your problem. ;)
But we still need to express the empty list case somehow. There are multiple ways to do this but the easiest would be the bool from Data.Bool function which is like an if function, together with join from Control.Monad.
-- [2]
bool x _ False = x
bool _ x True = x
join f x = f x x
Now we can do the following:
shout = join $ bool (not null case) (null case) . null
-- Which translates to
shout xs = bool ((not null case) xs) ((null case) xs) (null xs)
Again implementing the two cases is left as an excercise to the reader.
[1]: Instead of (.) you could also use (<$>) which for functions is the same as (.) but (<$>) and (<*>) kind of belong together. You will understand why once you learn about applicatives.
[2]: If you wonder what the reasoning behind the order of the arguments of bool is, the first argument is the False case because Bool is defined like this:
data Bool = False | True
And this order is motivated by the convention that False < True. maybe and either are two other functions that share this exact pattern with bool.
To rewrite anything in a pointfree style, install pointfree or use any one of the online versions (http://pointfree.io or https://blunt.herokuapp.com).
Your expression
\input -> (toUpper . head $ input) : (shout . tail $ input)
translates to
ap ((:) . toUpper . head) (shout . tail)
(You can substitute <*> for ap, they are interchangeable in this case).
But this is not enough. You also need to somehow end the recursion. To do that in the pointfree style you need a pointfree if or a pointfree pattern match which do not seem to exist in Haskell. In theory if could be defined as a built-in function, which would make a pointfree definition possible, but in Haskell it isn't. (One can define such a function, but its implementation would not be pointfree. So you can trade map for Data.Bool.bool, but is there a point?
Combinators like . and $ and even ap are probably not internally pointfree either, but using them doesn't feel like cheating. They only deal with functions, and thus feel somehow more fundamental than bool or map.
The point-free way to do recursion is to use Data.Function.fix, which is explained here: https://en.wikibooks.org/wiki/Haskell/Fix_and_recursion
Related
Hi I have task for writing a function that takes a list of functions from Int -> Int and a single Int and checks if any function when applied to that Int gives a result which is greater than 5.
This is my solution :
foo :: [Int -> Int] -> Int -> Bool
foo ls = any (>5) . f ls
where f ls v = map ($ v) ls
I would like to know is there a way to write this in single line (without using where or let) with eta reducing last argument (now it is eta reduced but it is not in single line). I tried something like this :
foo ls = any (>5) . flip map ls
But now the problem is call of function that looks like this for it to work
foo [(+3), (*4), (+1)] ($2)
I would like to avoid writin $ for last argument. I tried something like this (and similar to this) :
foo ls = any (>5) . flip map ls ($)
But I always get some kind of error. Be aware that I must not change the type signature, thus the flip.
Is there a way? Sure. Is it readable? No. Haskell's design pushes you away from some common mistakes, like unnecessary mutability or hidden use of (necessary) mutable state. But it makes it exciting to follow the path of other mistakes, like making code point-free in a manner harmful to readability and maintainability.
The thing about point-free definitions is that converting to them is a completely mechanical process (so long as pattern matching isn't involved in the starting definition). There are tools to do it automatically.
Start by writing the definition fully eta-expanded:
foo ls x = any (>5) (map ($ x) ls)
Then throw it into your favorite tool for doing the conversion. http://pointfree.io/ is an online service that will do it.
And it spits out the totally unreadable:
foo = (any (> 5) .) . flip (map . flip id)
Don't use that. It's not worth it.
But maybe you only wanted to eta-contract away one argument, and this is too much? Well, you can do that by cheating a little bit, and pretending the first argument is a value in scope, not an argument, and throwing the following definition in:
foo x = any (>5) (map ($ x) ls)
It returns foo = any (> 5) . flip map ls . flip id, which you then insert the argument back into:
foo ls = any (> 5) . flip map ls . flip id
This is mildly better, thanks to lacking sections of the (.) operator. But it still has flip id in it, which is obfuscation at its simplest.
Don't do it. Exercise restraint. Write code that's easy to read and modify.
Actually, your last trial in the question
foo ls = any (>5) . flip map ls ($)
is already very close to solution.
The only one problem is, considers the definition of ($):
($)::(a -> b) -> a -> b
the first argument of ($) is a function (a->b), but in your case, need be a value a, so just flip ($) swap the order of the arguments of ($) and put it back as:
foo ls = any (>5) . flip map ls . flip ($)
is the function that you want.
Starting with a fully non-reduced definition:
foo ls v = any (>5) (map (\f -> f v) ls)
We can use lambdabot to have a fully eta-reduced solution:
foo = (any (> 5) .) . flip (map . flip id)
However, this looks awful, and should not be recommended to do.
Since you have an applicative list at hand you may simply apply it with the applicative operator <*> as [(+3), (*4), (+1)] <*> [2] to obtain the list of results such as [5,8,3]. Now it's the any :: Foldable t => (a -> Bool) -> t a -> Bool function that comes handy. So all together
checker x = any (>5) $ [(+3), (*4), (+1)] <*> [x]
should do the job. If you need the pointfree version than it would be like
checker = any (>5) . ([(+3), (*4), (+1)] <*>) . pure
What is the difference between the dot (.) and the dollar sign ($)?
As I understand it, they are both syntactic sugar for not needing to use parentheses.
The $ operator is for avoiding parentheses. Anything appearing after it will take precedence over anything that comes before.
For example, let's say you've got a line that reads:
putStrLn (show (1 + 1))
If you want to get rid of those parentheses, any of the following lines would also do the same thing:
putStrLn (show $ 1 + 1)
putStrLn $ show (1 + 1)
putStrLn $ show $ 1 + 1
The primary purpose of the . operator is not to avoid parentheses, but to chain functions. It lets you tie the output of whatever appears on the right to the input of whatever appears on the left. This usually also results in fewer parentheses, but works differently.
Going back to the same example:
putStrLn (show (1 + 1))
(1 + 1) doesn't have an input, and therefore cannot be used with the . operator.
show can take an Int and return a String.
putStrLn can take a String and return an IO ().
You can chain show to putStrLn like this:
(putStrLn . show) (1 + 1)
If that's too many parentheses for your liking, get rid of them with the $ operator:
putStrLn . show $ 1 + 1
They have different types and different definitions:
infixr 9 .
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x = f (g x)
infixr 0 $
($) :: (a -> b) -> a -> b
f $ x = f x
($) is intended to replace normal function application but at a different precedence to help avoid parentheses. (.) is for composing two functions together to make a new function.
In some cases they are interchangeable, but this is not true in general. The typical example where they are is:
f $ g $ h $ x
==>
f . g . h $ x
In other words in a chain of $s, all but the final one can be replaced by .
Also note that ($) is the identity function specialised to function types. The identity function looks like this:
id :: a -> a
id x = x
While ($) looks like this:
($) :: (a -> b) -> (a -> b)
($) = id
Note that I've intentionally added extra parentheses in the type signature.
Uses of ($) can usually be eliminated by adding parenthesis (unless the operator is used in a section). E.g.: f $ g x becomes f (g x).
Uses of (.) are often slightly harder to replace; they usually need a lambda or the introduction of an explicit function parameter. For example:
f = g . h
becomes
f x = (g . h) x
becomes
f x = g (h x)
($) allows functions to be chained together without adding parentheses to control evaluation order:
Prelude> head (tail "asdf")
's'
Prelude> head $ tail "asdf"
's'
The compose operator (.) creates a new function without specifying the arguments:
Prelude> let second x = head $ tail x
Prelude> second "asdf"
's'
Prelude> let second = head . tail
Prelude> second "asdf"
's'
The example above is arguably illustrative, but doesn't really show the convenience of using composition. Here's another analogy:
Prelude> let third x = head $ tail $ tail x
Prelude> map third ["asdf", "qwer", "1234"]
"de3"
If we only use third once, we can avoid naming it by using a lambda:
Prelude> map (\x -> head $ tail $ tail x) ["asdf", "qwer", "1234"]
"de3"
Finally, composition lets us avoid the lambda:
Prelude> map (head . tail . tail) ["asdf", "qwer", "1234"]
"de3"
The short and sweet version:
($) calls the function which is its left-hand argument on the value which is its right-hand argument.
(.) composes the function which is its left-hand argument on the function which is its right-hand argument.
One application that is useful and took me some time to figure out from the very short description at Learn You a Haskell: Since
f $ x = f x
and parenthesizing the right hand side of an expression containing an infix operator converts it to a prefix function, one can write ($ 3) (4 +) analogous to (++ ", world") "hello".
Why would anyone do this? For lists of functions, for example. Both:
map (++ ", world") ["hello", "goodbye"]
map ($ 3) [(4 +), (3 *)]
are shorter than
map (\x -> x ++ ", world") ["hello", "goodbye"]
map (\f -> f 3) [(4 +), (3 *)]
Obviously, the latter variants would be more readable for most people.
Haskell: difference between . (dot) and $ (dollar sign)
What is the difference between the dot (.) and the dollar sign ($)?. As I understand it, they are both syntactic sugar for not needing to use parentheses.
They are not syntactic sugar for not needing to use parentheses - they are functions, - infixed, thus we may call them operators.
Compose, (.), and when to use it.
(.) is the compose function. So
result = (f . g) x
is the same as building a function that passes the result of its argument passed to g on to f.
h = \x -> f (g x)
result = h x
Use (.) when you don't have the arguments available to pass to the functions you wish to compose.
Right associative apply, ($), and when to use it
($) is a right-associative apply function with low binding precedence. So it merely calculates the things to the right of it first. Thus,
result = f $ g x
is the same as this, procedurally (which matters since Haskell is evaluated lazily, it will begin to evaluate f first):
h = f
g_x = g x
result = h g_x
or more concisely:
result = f (g x)
Use ($) when you have all the variables to evaluate before you apply the preceding function to the result.
We can see this by reading the source for each function.
Read the Source
Here's the source for (.):
-- | Function composition.
{-# INLINE (.) #-}
-- Make sure it has TWO args only on the left, so that it inlines
-- when applied to two functions, even if there is no final argument
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)
And here's the source for ($):
-- | 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
Conclusion
Use composition when you do not need to immediately evaluate the function. Maybe you want to pass the function that results from composition to another function.
Use application when you are supplying all arguments for full evaluation.
So for our example, it would be semantically preferable to do
f $ g x
when we have x (or rather, g's arguments), and do:
f . g
when we don't.
... or you could avoid the . and $ constructions by using pipelining:
third xs = xs |> tail |> tail |> head
That's after you've added in the helper function:
(|>) x y = y x
My rule is simple (I'm beginner too):
do not use . if you want to pass the parameter (call the function), and
do not use $ if there is no parameter yet (compose a function)
That is
show $ head [1, 2]
but never:
show . head [1, 2]
A great way to learn more about anything (any function) is to remember that everything is a function! That general mantra helps, but in specific cases like operators, it helps to remember this little trick:
:t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
and
:t ($)
($) :: (a -> b) -> a -> b
Just remember to use :t liberally, and wrap your operators in ()!
All the other answers are pretty good. But there’s an important usability detail about how ghc treats $, that the ghc type checker allows for instatiarion with higher rank/ quantified types. If you look at the type of $ id for example you’ll find it’s gonna take a function whose argument is itself a polymorphic function. Little things like that aren’t given the same flexibility with an equivalent upset operator. (This actually makes me wonder if $! deserves the same treatment or not )
The most important part about $ is that it has the lowest operator precedence.
If you type info you'll see this:
λ> :info ($)
($) :: (a -> b) -> a -> b
-- Defined in ‘GHC.Base’
infixr 0 $
This tells us it is an infix operator with right-associativity that has the lowest possible precedence. Normal function application is left-associative and has highest precedence (10). So $ is something of the opposite.
So then we use it where normal function application or using () doesn't work.
So, for example, this works:
λ> head . sort $ "example"
λ> e
but this does not:
λ> head . sort "example"
because . has lower precedence than sort and the type of (sort "example") is [Char]
λ> :type (sort "example")
(sort "example") :: [Char]
But . expects two functions and there isn't a nice short way to do this because of the order of operations of sort and .
I think a short example of where you would use . and not $ would help clarify things.
double x = x * 2
triple x = x * 3
times6 = double . triple
:i times6
times6 :: Num c => c -> c
Note that times6 is a function that is created from function composition.
I wrote this code and I have to rewrite it to the pointfree style:
num_of_occ ele list = length(filter(==ele)list)
So I did this:
num_of_occ ele = length . filter((==)ele)
It works. Than I did this:
num_of_occ = length . filter . (==)
And it doesnt... what's wrong with my line of thought?
This is a common error. Here is the fix:
num_of_occ = (length .) . filter . (==)
It has to do with the number of arguments your function takes. The function composition (.) operator works on functions with one argument, you need to apply it twice (f .) . to make it work on functions with two arguments.
There's actually a program on Hackage that will automatically convert a snippet of code to points free style, if you want to play with it.
$ cabal install pointfree
$ pointfree 'num_of_occ ele list = length (filter (== ele) list)'
num_of_occ = (length .) . filter . (==)
As noted, this needs a type signature to work correctly. The reasons for this are relatively mundane but obscure, and the restriction exists to improve Haskell performance. You can turn on the NoMonomorphismRestriction extension, or add a type signature:
num_of_occ :: Eq a => a -> [a] -> Int
num_of_occ = (length .) . filter . (==)
I've started to wrap my head around it, and rather like using it for simple situations in which I can essentially pipe the values from one output to one input. A simple example of a pointfree composition I'm comfortable with would be:
let joinLines = foldr (++) "" . intersperse "\n"
While playing with GHCI today, I wanted to see if I could compose not and (==) to replicate (/=), but I wasn't really able to reason it out. (==) take two inputs, and not takes one. I thought that this might work:
let ne = not . (==)
With the assumption that the single Bool output of (==) would go to not, but it won't compile, citing the following error:
<interactive>:1:16:
Couldn't match expected type `Bool' with actual type `a0 -> Bool'
Expected type: a0 -> Bool
Actual type: a0 -> a0 -> Bool
In the second argument of `(.)', namely `(==)'
In the expression: not . (==)
I wish I could say it meant much to me, but all I'm getting is that maybe the second argument that's passed to (==) is mucking things up for not? Can anybody help me understand a little better the logic behind this composition?
If you start to remove one argument at the time, you get
ne x y = not (x == y)
= (not . (x ==)) y
ne x = not . (x ==)
= not . ((==) x)
= ((not .) . (==)) x
ne = (not .) . (==)
basically, for every argument you need one (.), properly associated.
The type of (==) is Eq a => a -> a -> Bool. So if you write whatever . (==), and pass a value x to that, you get whatever ((==) x), but (==) x is a function a -> Bool (where a is the type of x, and an instance of Eq). So the whatever must accept arguments of function type.
Another useful operator is (.:), which is a combinator for an initial function taking two arguments:
f . g $ x
f .: g $ x y
Explicit use of curry and uncurry can help switch between "multi-argument" and single-argument functions.
ne = curry (not . uncurry (==))
uncurry "fixes" (==) so that it takes a single argument (x,y) rather than separate x and y arguments. The resulting function can then be composed with not as expected. The composed function, then can be re-curried to accept separate arguments again.
I am not sure if this makes any sense... but it looks readable to me
ne = (.) not . (==)
I have just began recently to learn Haskell, more specifically on the topics of function composition, partial functions, maps, filters and sectioning. On one of the exercises am asked to modify the twoFilters function by using function composition.
I have read a few wikis on . but am having quite a hard time getting it to work correctly. As i understand it, it works by performing the functions b . a on alphabetical order and returning the result. In other words x = foo a and then foo b of x. However after applying several "variations/possibilities" with the bellow two filters functions i cant get it to compile due to errors.
greaterThanOne :: Int -> Bool
greaterThanOne = (>1)
lessThanTen :: Int -> Bool
lessThanTen = (<10)
twoFilters :: [Int] -> [Int]
twoFilters xs= filter lessThanTen (filter greaterThanOne xs)
These two being the unsuccessful attempts I had most confidence on;
twoFilters xs = filter (lessThanTen . greaterThanOne xs)
twoFilters xs = filter (lessThanTen xs . greaterThanOne xs)
Where on the reasoning am I going wrong?
The attempts you were confident about are a simple failure in your logic: the dot operator works like this:
(f.g)(x) = f(g(x))
So, trying to compute an example of 5 gives:
lessThanThen(greaterThanOne(5)) = lessThanTen(True) -- that can't be right, can it???
What you want is a lambda and &&:
filter (\x-> (lessThanThen x) && greaterThanOne(x))
Alternatively, you can use two filters:
filter lessThanTen . filter greaterThanOne $
Enter the wonderful world of Applicative Functors:
import Control.Applicative
greaterThanOne = (>1)
lessThanTen = (<10)
twoFilters = filter ((&&) <$> greaterThanOne <*> lessThanTen)
twoFilters [1,2,3,4,5,6,7,8,9,10]
-- [2,3,4,5,6,7,8,9]
Read Learn you a Haskell - Applicative Functors for a detailed explanation.
You can't compose those two functions like this. f . g works like composition in maths, i.e. is equivalent to f(g(x)). That means the outer function must take an argument of a type that inner function returns, in your case the outer function would have to be Bool -> Bool.
You can write your twoFilters using composition operator like this:
twoFilters = (filter lessThanTen) . (filter greaterThanOne)
(.) expects a function which takes one argument and returns a value, but you pass it a Bool value in:
lessThanTen . greaterThanOne xs
which is wrong.
Here:
lessThanTen xs . greaterThanOne xs
you're trying to compose two Bool values, but you should've composed two functions which return Bool values.
One issue it that function application has highest precedence. So lessThanTen . greaterThanOne xs tries to compose lessThanTen with the result of greaterThanOne xs (which doesn't work to start with, the function works on integers, not on lists thereof). Likewise, lessThanTen xs. greaterThanOne xs tries to compose the results of those function calls (assuming they'd make sense in the first place), not the functions themself.
Another problem is a misunderstanding of . - (f . g) x is equivalent to f (g x), i.e. the result of the first function is the argument for the second. So the type of g must be (a -> b) and the type of f must be (b -> c) (both b are the same type variable!). What you want to apply both functions to the same argument and join the results with &&. There's no existing functions for this as far as I know (at least Hoogle didn't find anything for (a -> Bool) -> (a -> Bool) -> a -> Bool). You'll have to make your own:
both f g x = f x && g x
Alternatively, you coudl just stick to filtering twice (which isn't as bad as it sounds thanks to lazy evaluation) - filter (>1) $ filter (<10) xs.
As i understand it, it works by performing the functions b . a on alphabetical order and returning the result. In other words x = foo a and then foo b of x
This could be written in Haskell as
let x = foo a in
foo b x
(where does foo come from?) but the correct
(b . a) x = let y = a x in
b y
Or, shorter:
(b . a) x = b (a x)
Now, filter lessThanTen (filter greaterThanOne xs) has a similar shape to the right side of this definition, if you remember you could write it as (filter lessThanTen) ((filter greaterThanOne) xs):
((filter lessThanTen) . (filter greaterThanOne)) xs
Presumably what you actually want is filter ??? xs, but that should be enough to go on with.
You have it almost right. I find the easiest way to start learning function composition with . is to use $ first instead.
So you have a list
twoFilters xs = xs
You want to filter by greaterThanOne
twoFilters xs = filter greaterThanOne $ xs
You additionally want to filter by lessThanTen
twoFilters xs = filter lessThanTen $ filter greaterThanOne $ xs
Now move from left to right, replacing all $s with . except for the last $
twoFilters xs = filter lessThanTen . filter greaterThanOne $ xs
You could use parenthesis instead of $ now:
twoFilters xs = (filter lessThanTen . filter greaterThanOne) xs
Or just define the function pointfree:
twoFilters = filter lessThanTen . filter greaterThanOne
The parenthesized version is the most important, I think. It shows that you fuse the two partially-applied functions filter lessThanTen and filter greaterThanOne into one mega-filtering function, with . and then you apply the list to it. You need to parenthesize them because . binds less tightly than function application via whitespace (space can be considered an uber-high-fixity version of $). Remember, when you use ., you are fusing two functions together to form one mega-function.
It is relevant to inspect the type signature of .
(.) :: (b -> c) -> (a -> b) -> a -> c
The functions you feed it have to "line up" with very particular type signatures (they have to be compatible for fusing). But honestly, the key is learning to recognize when function application (with space) is binding more tightly than you intend and messing up the type signatures of functions you are trying to compose. That's how it was for me, anyways.