Can't get point free notation to compile in Haskell - haskell

This is working
unique :: (a -> Bool) -> [a] -> Bool
unique p xs = 1 == length (filter p xs)
But now I want it in the form:
unique = (== 1) . length . filter
Error message:
Couldn't match expected type `[a] -> Bool' with actual type `Bool'
Expected type: b0 -> [a] -> Bool
Actual type: b0 -> Bool
In the first argument of `(.)', namely `(== 1)'
In the expression: (== 1) . length . filter
Why is this not working?

This is because filter is a two argument function. You can get around this using the handy operator
(.:) = (c -> d) -> (a -> b -> c) -> a -> b -> d
(.:) = (.) . (.)
-- Important to make it the same precedence as (.)
infixr 9 .:
unique = ((== 1) . length) .: filter
If you look at the type of (length .) in GHCi, you'll get
(length .) :: (a -> [b]) -> a -> Int
This means that it takes a single argument function that returns a list. If we look at the type of filter:
filter :: (a -> Bool) -> [a] -> [a]
This can be rewritten to make it "single argument" as
filter :: (a -> Bool) -> ([a] -> [a])
And this quite clearly does not line up with a -> [b]! In particular, the compiler can't figure out how to make ([a] -> [a]) be the same as [b], since one is a function on lists, and the other is simply a list. So this is the source of the type error.
Interestingly, the .: operator can be generalized to work on functors instead:
(.:) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
(.:) = fmap fmap fmap
-- Since the first `fmap` is for the (->) r functor, you can also write this
-- as (.:) = fmap `fmap` fmap === fmap . fmap
What is this good for? Say you have a Maybe [[Int]], and you wanted the sum of each sublist inside the Just, provided it exists:
> let myData = Just [[3, 2, 1], [4], [5, 6]]
> sum .: myData
Just [6, 4, 11]
> length .: myData
Just [3, 1, 2]
> sort .: myData
Just [[1,2,3],[4],[5,6]]
Or what if you had a [Maybe Int], and you wanted to increment each one:
> let myData = [Just 1, Nothing, Just 3]
> (+1) .: myData
[Just 2,Nothing,Just 4]
The possibilities go on and on. Basically, it lets you map a function inside two nested functors, and this sort of structure crops up pretty often. If you've ever had a list inside a Maybe, or tuples inside a list, or IO returning a string, or anything like that, you've come across a situation where you could use (.:) = fmap fmap fmap.

Related

Why can't I compose before currying two arguments? [duplicate]

I am trying to compose a function of type (Floating a) => a -> a -> a with a function of type (Floating a) => a -> a to obtain a function of type (Floating a) => a -> a -> a. I have the following code:
test1 :: (Floating a) => a -> a -> a
test1 x y = x
test2 :: (Floating a) => a -> a
test2 x = x
testBoth :: (Floating a) => a -> a -> a
testBoth = test2 . test1
--testBoth x y = test2 (test1 x y)
However, when I compile it in GHCI, I get the following error:
/path/test.hs:8:11:
Could not deduce (Floating (a -> a)) from the context (Floating a)
arising from a use of `test2'
at /path/test.hs:8:11-15
Possible fix:
add (Floating (a -> a)) to the context of
the type signature for `testBoth'
or add an instance declaration for (Floating (a -> a))
In the first argument of `(.)', namely `test2'
In the expression: test2 . test1
In the definition of `testBoth': testBoth = test2 . test1
Failed, modules loaded: none.
Note that the commented-out version of testBoth compiles. The strange thing is that if I remove the (Floating a) constraints from all type signatures or if I change test1 to just take x instead of x and y, testBoth compiles.
I've searched StackOverflow, Haskell wikis, Google, etc. and not found anything about a restriction on function composition relevant to this particular situation. Does anyone know why this is happening?
\x y -> test2 (test1 x y)
== \x y -> test2 ((test1 x) y)
== \x y -> (test2 . (test1 x)) y
== \x -> test2 . (test1 x)
== \x -> (test2 .) (test1 x)
== \x -> ((test2 .) . test1) x
== (test2 .) . test1
These two things are not like each other.
test2 . test1
== \x -> (test2 . test1) x
== \x -> test2 (test1 x)
== \x y -> (test2 (test1 x)) y
== \x y -> test2 (test1 x) y
You're problem doesn't have anything to do with Floating, though the typeclass does make your error harder to understand. Take the below code as an example:
test1 :: Int -> Char -> Int
test1 = undefined
test2 :: Int -> Int
test2 x = undefined
testBoth = test2 . test1
What is the type of testBoth? Well, we take the type of (.) :: (b -> c) -> (a -> b) -> a -> c and turn the crank to get:
b ~ Int (the argument of test2 unified with the first argument of (.))
c ~ Int (the result of test2 unified with the result of the first argument of (.))
a ~ Int (test1 argument 1 unified with argument 2 of (.))
b ~ Char -> Int (result of test1 unified with argument 2 of (.))
but wait! that type variable, 'b' (#4, Char -> Int), has to unify with the argument type of test2 (#1, Int). Oh No!
How should you do this? A correct solution is:
testBoth x = test2 . test1 x
There are other ways, but I consider this the most readable.
Edit: So what was the error trying to tell you? It was saying that unifying Floating a => a -> a with Floating b => b requires an instance Floating (a -> a) ... while that's true, you really didn't want GHC to try and treat a function as a floating point number.
Your problem has nothing to do with Floating, but with the fact that you want to compose a function with two arguments and a function with one argument in a way that doesn't typecheck. I'll give you an example in terms of a composed function reverse . foldr (:) [].
reverse . foldr (:) [] has the type [a] -> [a] and works as expected: it returns a reversed list (foldr (:) [] is essentially id for lists).
However reverse . foldr (:) doesn't type check. Why?
When types match for function composition
Let's review some types:
reverse :: [a] -> [a]
foldr (:) :: [a] -> [a] -> [a]
foldr (:) [] :: [a] -> [a]
(.) :: (b -> c) -> (a -> b) -> a -> c
reverse . foldr (:) [] typechecks, because (.) instantiates to:
(.) :: ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
In other words, in type annotation for (.):
a becomes [a]
b becomes [a]
c becomes [a]
So reverse . foldr (:) [] has the type [a] -> [a].
When types don't match for function composition
reverse . foldr (:) doesn't type check though, because:
foldr (:) :: [a] -> [a] -> [a]
Being the right operant of (.), it would instantiate its type from a -> b to [a] -> ([a] -> [a]). That is, in:
(b -> c) -> (a -> b) -> a -> c
Type variable a would be replaced with [a]
Type variable b would be replaced with [a] -> [a].
If type of foldr (:) was a -> b, the type of (. foldr (:)) would be:
(b -> c) -> a -> c`
(foldr (:) is applied as a right operant to (.)).
But because type of foldr (:) is [a] -> ([a] -> [a]), the type of (. foldr (:)) is:
(([a] -> [a]) -> c) -> [a] -> c
reverse . foldr (:) doesn't type check, because reverse has the type [a] -> [a], not ([a] -> [a]) -> c!
Owl operator
When people first learn function composition in Haskell, they learn that when you have the last argument of function at the right-most of the function body, you can drop it both from arguments and from the body, replacing or parentheses (or dollar-signs) with dots. In other words, the below 4 function definitions are equivalent:
f a x xs = g ( h a ( i x xs))
f a x xs = g $ h a $ i x xs
f a x xs = g . h a . i x $ xs
f a x = g . h a . i x
So people get an intuition that says “I just remove the right-most local variable from the body and from the arguments”, but this intuition is faulty, because once you removed xs,
f a x = g . h a . i x
f a = g . h a . i
are not equivalent! You should understand when function composition typechecks and when it doesn't. If the above 2 were equivalent, then it would mean that the below 2 are also equivalent:
f a x xs = g . h a . i x $ xs
f a x xs = g . h a . i $ x xs
which makes no sense, because x is not a function with xs as a parameter. x is a parameter to function i, and xs is a parameter to function (i x).
There is a trick to make a function with 2 parameters point-free. And that is to use an “owl” operator:
f a x xs = g . h a . i x xs
f a = g . h a .: i
where (.:) = (.).(.)
The above two function definitions are equivalent. Read more on “owl” operator.
References
Haskell programming becomes much easier and straightforward, once you understand functions, types, partial application and currying, function composition and dollar-operator. To nail these concepts, read the following StackOverflow answers:
On types and function composition
On higher-order functions, currying, and function composition
On Haskell type system
On point-free style
On const
On const, flip and types
On curry and uncurry
Read also:
Haskell: difference between . (dot) and $ (dollar sign)
Haskell function composition (.) and function application ($) idioms: correct use

Websocket example in haskell uses special characters as functions

> type Client = (Text, WS.Connection)
The state kept on the server is simply a list of connected clients. We've added
an alias and some utility functions, so it will be easier to extend this state
later on.
> type ServerState = [Client]
Check if a user already exists (based on username):
> clientExists :: Client -> ServerState -> Bool
> clientExists client = any ((== fst client) . fst)
Remove a client:
> removeClient :: Client -> ServerState -> ServerState
> removeClient client = filter ((/= fst client) . fst)
This is a literal haskell code taken from websockets. I don't understand how does clientExists function works,
clientExists client = any ((== fst client) . fst)
This function is invoked as,
clientExists client clients
So, how does the function refer the second argument clients? and what does . operator do?
And again at removeClient, what does the operator `/=' stand for?
The . operator is the function composition operator, it's defined as
f . g = \x -> f (g x)
The /= operator is "not equals", usually written as != in other languages.
The clientExists function has two arguments, but the second one is left off since it's redundant. It could have been written as
clientExists client clients = all ((== fst client) . fst) clients
But Haskell allows you to drop the last argument in situations like this. The any function has the type (a -> Bool) -> [a] -> Bool, and the function any ((== fst client) . fst) has the type [a] -> Bool. This is saying that the function clientExists client is the same function as any ((== fst client) . fst).
Another way to think of it is that Haskell does not have multi-argument functions, only single argument functions that return new functions. This is because -> is right associative, so a type signature like
a -> b -> c -> d
Can be written as
a -> (b -> (c -> d))
without changing its meaning. With the second type signature it's more clear that you have a function that when given an a, returns a function of type b -> (c -> d). If it's next given a b, it returns a function of type c -> d. Finally, if this is given a c it just returns a d. Since function application in Haskell is so cheap (just a space), this is transparent, but it comes in handy. For example, it means that you can write code like
incrementAll = map (+1)
or
onlyPassingStudents = filter ((>= 70) . grade)
In both of these cases I've also used operator sections, where you can supply either argument to an operator, and so long as its wrapped in parens it works. Internally it looks more like
(x +) = \y -> x + y
(+ x) = \y -> y + x
Where you can swap out the + for any operator you please. If you were to expand the definition of clientExists to have all argument specified it would look more like
clientExists client clients = any (\c -> fst c == fst client) clients
This definition is exactly equivalent to the one you have, just de-sugared to what the compiler really uses internally.
When in doubt, use the GHCi interpreter to find out the types of the functions.
First off, the /= operator is the not-equal:
ghci> :t (/=)
(/=) :: Eq a => a -> a -> Bool
ghci> 5 /= 5
False
ghci> 10 /= 5
True
. is the composition of two functions. It glues two functions together, just like in mathematics:
ghci> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
ghci> :t head.tail
head.tail :: [c] -> c
ghci> (head.tail) [1, 2, 3]
2
With the basics covered, let's see how it is used in your function definition:
ghci> :t (\x -> (== fst x))
(\x-> (== fst x)) :: Eq a => (a, b) -> a -> Bool
ghci> :t (\x-> (== fst x) . fst)
(\x-> (== fst x) . fst) :: Eq b => (b, b1) -> (b, b2) -> Bool
ghci> (\x -> (== fst x) . fst) (1, "a") (1, "b")
True
ghci> (\x -> (== fst x) . fst) (1, "a") (2, "b")
False
As we can see, the (== fst x) . fst is used to take two tuples, and compare the first element each for equality. Now, this expression (let's call it fstComp) has type fstComp :: Eq b => (b, b1) -> (b, b2) -> Bool, but we are already passing it a defined tuple (client :: (Text, WS.Connection)), we curry it to (Text, b2) -> Bool.
Since we have any :: (a -> Bool) -> [a] -> Bool, we can unify the first parameter with the previous type to have an expression of type (Text, b2) -> [(Text, b2)] -> Bool. Instantiating b2 = WS.Connection we get the type of clientExists :: (Text, WS.Connection) -> [(Text, WS.Connection)] -> Bool, or using the type synonyms, clientExists :: Client -> ServerState -> Bool.

How to use (.) in Haskell

I'm trying to write something like this in Haskell:
length . nub . intersect
but it doesn't work.
*Main Data.List> :t intersect
intersect :: Eq a => [a] -> [a] -> [a]
*Main Data.List> :t nub
nub :: Eq a => [a] -> [a]
*Main Data.List> :t length
length :: [a] -> Int
Based on the type, my understanding is that intersect returns a type of [a] and donates to nub , which takes exactly a type of [a] , then also returns a type of [a] to length , then finally the return should be an Int. What's wrong with it?
The problem here is that intersect takes 2 arguments (in a sense)
you can provide one of the arguments explicitly:
> let f a = length . nub . intersect a
> :t f
f :: Eq a => [a] -> [a] -> Int
or you can use a fun little operator like (.:) = (.) . (.):
> let (.:) = (.) . (.)
> :t length .: (nub .: intersect)
length .: (nub .: intersect) :: Eq a => [a] -> [a] -> Int
here is a version where you don't need the parens:
import Data.List
infixr 9 .:
(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
(.:) = (.).(.)
f :: Eq a => [a] -> [a] -> Int
f = length .: nub .: intersect
I guess this is based on the comments in your previous question, where #CarstenKönig mentions (.) . (.).
First of all, length . nub . intersect cannot work. Your types are:
(.) :: (b -> c) -> (a -> b) -> (a -> c)
length :: [a] -> Int
nub :: Eq a => [a] -> [a]
intersect :: Eq a => [a] -> [a] -> [a] ~ [a] -> ([a] -> [a])
As you can see, intersect has the wrong type, in the context of (.), the type parameter b would be replaced by ([a] -> [a]), which isn't the type of nub's first argument.
I'd say this: write your code the "dumb" way at first, and then refactor it to use (.). After some practice the composition operator will then become like second nature.
So you'd first write:
yourFunction xs ys = length (nub (intersect xs ys))
What (.) lets you do is get rid (syntactically) of the last argument of the innermost function, all all the parens. In this case that argument is ys:
yourFunction xs = length . nub . intersect xs

Mapping `apply` to List of Functions

Learn You a Haskell demonstrates mapping with currying:
*Main> let xs = map (*) [1..3]
xs now equals [(1*), (2*), (3*)]
EDITED to correct order per Antal S-Z's comment.
We can get the first item in the list, and apply 3 to it - returning 3*1.
*Main> (xs !! 0) 3
3
But, how can I apply the below foo to apply 1 to all curried functions in xs?
*Main> let foo = 1
*Main> map foo xs
<interactive>:160:5:
Couldn't match expected type `(Integer -> Integer) -> b0'
with actual type `Integer'
In the first argument of `map', namely `foo'
In the expression: map foo xs
In an equation for `it': it = map foo xs
Desired output:
[1, 2, 3]
Use the ($) function...
Prelude> :t ($)
($) :: (a -> b) -> a -> b
...passing just the second argument to it.
Prelude> let foo = 2
Prelude> map ($ foo) [(1*), (2*), (3*)]
[2,4,6]
Have you tried using applicative functors?
import Control.Applicative
main = (*) <$> [1,2,3] <*> pure 1
The <$> function is the same as fmap in infix form. It has the type signature:
(<$>) :: Functor f => (a -> b) -> f a -> f b
The <*> function is the functor equivalent of $ (function application):
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
The pure function is similar to return for monads. It takes a normal value and returns an applicative functor:
pure :: Applicative f => a -> f a
Hence the expression (*) <$> [1,2,3] <*> pure 1 is similar to applying the (*) function to all the values of [1,2,3] and pure 1. Since pure 1 only has one value it is equivalent to multiplying every item of the list with 1 to produce a new list of products.
Or you could use anonymous function:
map (\x -> x foo) xs

Haskell: composing function with two floating arguments fails

I am trying to compose a function of type (Floating a) => a -> a -> a with a function of type (Floating a) => a -> a to obtain a function of type (Floating a) => a -> a -> a. I have the following code:
test1 :: (Floating a) => a -> a -> a
test1 x y = x
test2 :: (Floating a) => a -> a
test2 x = x
testBoth :: (Floating a) => a -> a -> a
testBoth = test2 . test1
--testBoth x y = test2 (test1 x y)
However, when I compile it in GHCI, I get the following error:
/path/test.hs:8:11:
Could not deduce (Floating (a -> a)) from the context (Floating a)
arising from a use of `test2'
at /path/test.hs:8:11-15
Possible fix:
add (Floating (a -> a)) to the context of
the type signature for `testBoth'
or add an instance declaration for (Floating (a -> a))
In the first argument of `(.)', namely `test2'
In the expression: test2 . test1
In the definition of `testBoth': testBoth = test2 . test1
Failed, modules loaded: none.
Note that the commented-out version of testBoth compiles. The strange thing is that if I remove the (Floating a) constraints from all type signatures or if I change test1 to just take x instead of x and y, testBoth compiles.
I've searched StackOverflow, Haskell wikis, Google, etc. and not found anything about a restriction on function composition relevant to this particular situation. Does anyone know why this is happening?
\x y -> test2 (test1 x y)
== \x y -> test2 ((test1 x) y)
== \x y -> (test2 . (test1 x)) y
== \x -> test2 . (test1 x)
== \x -> (test2 .) (test1 x)
== \x -> ((test2 .) . test1) x
== (test2 .) . test1
These two things are not like each other.
test2 . test1
== \x -> (test2 . test1) x
== \x -> test2 (test1 x)
== \x y -> (test2 (test1 x)) y
== \x y -> test2 (test1 x) y
You're problem doesn't have anything to do with Floating, though the typeclass does make your error harder to understand. Take the below code as an example:
test1 :: Int -> Char -> Int
test1 = undefined
test2 :: Int -> Int
test2 x = undefined
testBoth = test2 . test1
What is the type of testBoth? Well, we take the type of (.) :: (b -> c) -> (a -> b) -> a -> c and turn the crank to get:
b ~ Int (the argument of test2 unified with the first argument of (.))
c ~ Int (the result of test2 unified with the result of the first argument of (.))
a ~ Int (test1 argument 1 unified with argument 2 of (.))
b ~ Char -> Int (result of test1 unified with argument 2 of (.))
but wait! that type variable, 'b' (#4, Char -> Int), has to unify with the argument type of test2 (#1, Int). Oh No!
How should you do this? A correct solution is:
testBoth x = test2 . test1 x
There are other ways, but I consider this the most readable.
Edit: So what was the error trying to tell you? It was saying that unifying Floating a => a -> a with Floating b => b requires an instance Floating (a -> a) ... while that's true, you really didn't want GHC to try and treat a function as a floating point number.
Your problem has nothing to do with Floating, but with the fact that you want to compose a function with two arguments and a function with one argument in a way that doesn't typecheck. I'll give you an example in terms of a composed function reverse . foldr (:) [].
reverse . foldr (:) [] has the type [a] -> [a] and works as expected: it returns a reversed list (foldr (:) [] is essentially id for lists).
However reverse . foldr (:) doesn't type check. Why?
When types match for function composition
Let's review some types:
reverse :: [a] -> [a]
foldr (:) :: [a] -> [a] -> [a]
foldr (:) [] :: [a] -> [a]
(.) :: (b -> c) -> (a -> b) -> a -> c
reverse . foldr (:) [] typechecks, because (.) instantiates to:
(.) :: ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
In other words, in type annotation for (.):
a becomes [a]
b becomes [a]
c becomes [a]
So reverse . foldr (:) [] has the type [a] -> [a].
When types don't match for function composition
reverse . foldr (:) doesn't type check though, because:
foldr (:) :: [a] -> [a] -> [a]
Being the right operant of (.), it would instantiate its type from a -> b to [a] -> ([a] -> [a]). That is, in:
(b -> c) -> (a -> b) -> a -> c
Type variable a would be replaced with [a]
Type variable b would be replaced with [a] -> [a].
If type of foldr (:) was a -> b, the type of (. foldr (:)) would be:
(b -> c) -> a -> c`
(foldr (:) is applied as a right operant to (.)).
But because type of foldr (:) is [a] -> ([a] -> [a]), the type of (. foldr (:)) is:
(([a] -> [a]) -> c) -> [a] -> c
reverse . foldr (:) doesn't type check, because reverse has the type [a] -> [a], not ([a] -> [a]) -> c!
Owl operator
When people first learn function composition in Haskell, they learn that when you have the last argument of function at the right-most of the function body, you can drop it both from arguments and from the body, replacing or parentheses (or dollar-signs) with dots. In other words, the below 4 function definitions are equivalent:
f a x xs = g ( h a ( i x xs))
f a x xs = g $ h a $ i x xs
f a x xs = g . h a . i x $ xs
f a x = g . h a . i x
So people get an intuition that says “I just remove the right-most local variable from the body and from the arguments”, but this intuition is faulty, because once you removed xs,
f a x = g . h a . i x
f a = g . h a . i
are not equivalent! You should understand when function composition typechecks and when it doesn't. If the above 2 were equivalent, then it would mean that the below 2 are also equivalent:
f a x xs = g . h a . i x $ xs
f a x xs = g . h a . i $ x xs
which makes no sense, because x is not a function with xs as a parameter. x is a parameter to function i, and xs is a parameter to function (i x).
There is a trick to make a function with 2 parameters point-free. And that is to use an “owl” operator:
f a x xs = g . h a . i x xs
f a = g . h a .: i
where (.:) = (.).(.)
The above two function definitions are equivalent. Read more on “owl” operator.
References
Haskell programming becomes much easier and straightforward, once you understand functions, types, partial application and currying, function composition and dollar-operator. To nail these concepts, read the following StackOverflow answers:
On types and function composition
On higher-order functions, currying, and function composition
On Haskell type system
On point-free style
On const
On const, flip and types
On curry and uncurry
Read also:
Haskell: difference between . (dot) and $ (dollar sign)
Haskell function composition (.) and function application ($) idioms: correct use

Resources