I need to write on a module to be run on GHCi, with a function composition to the same function. This (The classic fog(x) = f(g(x))) runs:
(.) f g = (\x -> f (g x)).
The problem appears when I try to write it like this
(.) f f = (\x -> f (f x)). (fof(x) = f(f(x)))
GHCi says:
"Conflicting definitions for `f'
Bound at: Lab1.hs:27:9
Lab1.hs:27:12"
Line 27:9 appear on the first time f and line 27:12 appear f again.
Why doesn't Haskell understand (.) f f = (\x -> f (f x))?
In Haskell, arguments to a function must have unique names. Using the same name for another argument is not allowed. This is because
foo x y = ... === foo = (\x-> (\y-> ...))
and if y where replaced with x, the second x would just shadow the first inside the ... body: there would be no way to reference the first x from there.
You can just define twice f x = f (f x):
Prelude> :t twice
twice :: (t -> t) -> t -> t
Prelude> twice (+1) 4
6
Alternatively, f (f x) = (.) f f x = join (.) f x:
Prelude Control.Monad> :t join (.)
join (.) :: (b -> b) -> b -> b
join is defined in Control.Monad. For functions, it holds that join g x = g x x. It is also known as W combinator.
E.g. print $ join (.) (+1) 4 prints 6.
As the error message says, you have conflicting definitions for f in the definition (.) f f = (\x -> f (f x)). You are binding the name f to both the first and second arguments to (.), so ghci doesn't know which argument to use when evaluating the expression f x.
There is nothing wrong with defining (.) using the pattern (.) f g, and then calling it with two arguments that happen to be the same.
Related
I have a problem with understanding what the compiler does when I enter this:
(curry . uncurry) (+) 1 2
After my understanding the compiler goes with uncurry first which would mean that an error would occur because the uncurry function needs an input like this:
(curry . uncurry) (+) (1,2)
but obviously the first one is right. I don't get why though.
What exactly are the steps the compiler takes when evaluating this?
Another topic included question:
Why does
(uncurry . curry) (+) (1,2)
does not work?
After my understanding the compiler goes with uncurry.
No it goes with the (curry . uncurry)
If we evaluate the (curry . uncurry) function we see that this short for:
\x -> curry (uncurry x)
so the (curry . uncurry) (+) 1 2 function is short for:
(\x -> curry (uncurry x)) (+) 1 2
or thus:
(curry (uncurry (+))) 1 2
and uncurry :: (a -> b -> c) -> (a, b) -> c and curry :: ((a, b) -> c) -> a -> b -> c thus transform a function. This thus means that uncurry (+) indeed expects a 2-tuple:
uncurry (+) :: Num a => (a, a) -> a
but now pass this function through the curry function:
curry (uncurry (+)) :: Num a => a -> a -> a
so the curry function undoes the transformation the uncurry made to the (+) function. This thus means that curry (uncurry (+)) is the same as (+), and thus:
(curry (uncurry (+))) 1 2
is equivalent to:
(+) 1 2
and this is thus equivalent to 3.
The curry . uncurry is not completely equivalent to id however, since it has as type:
curry . uncurry :: (a -> b -> c) -> a -> b -> c
this thus means that it restricts the function to a function of type a -> (b -> c).
Your expression parses as
(((curry . uncurry) (+)) 1) 2
so, it builds the function (curry . uncurry) (+) and applies it to 1, then the resulting function is applied to 2.
Hence, we start from (curry . uncurry) (+) which means curry (uncurry (+)). Assume for simplicity that (+) is implemented as
(+) = \x y -> ...
Note the above is an curried function, taking x and then y as separate arguments. We then have:
curry (uncurry (+))
= { definition + }
curry (uncurry (\x y -> ...)) -- note the separate arguments
= { definition uncurry }
curry (\(x, y) -> ...) -- only one pair argument
= { definition curry }
(\x y -> ...) -- back to two arguments
= { definition + }
(+)
Above, uncurry transforms the function + into one that accepts a single pair argument instead of two. This transformation is reversed by curry, which breaks the pair argument into two separate ones.
Indeed, curry . uncurry is the identity transformation on binary curried functions since it applies a transformation and its inverse. Hence, it has no effect on the result, or on the type of the functions involved.
We conclude that your expression is equivalent to ((+) 1) 2, which evaluates to 3.
This question got great answers, yet I would like to add a note about curry . uncurry.
You might have heard of SKI-calculus. If you haven't, it is a calculus where we work with 3 combinators:
Sabc = ac(bc)
Kab = a
Ia = a
It is widely known to be Turing-full.
Besides, the I combinator is redundant. Let us try writing it down in terms of S and K combinators.
The main idea is that the only argument of I should be passed as the first argument of K, whose second argument is occupied. That is exactly what the S combinator does: if we pass K as the first argument of S, we would have it return the third argument of S:
SKbc = Kc(bc) = c
We have shown that (K*ab = b):
K* = SK
Therefore, we just need to choose the second argument: both K and S would do:
I = SKK = SKS
As one can see, combinator I corresponds to id;
combinator K corresponds to const;
and combinator S corresponds to (<*>) :: (e -> a -> b) -> (e -> a) -> e -> b.
I = SKK corresponds to const <*> const :: a -> a.
Our other results (I = SKS and K* = SK) do not hold in Haskell due to typing:
GHCi> :t (<*>) const (<*>) {- id -}
(<*>) const (<*>) {- id -}
:: Applicative f => f (a -> b) -> f (a -> b)
GHCi> :t (const <*>) {- flip const -}
(const <*>) {- flip const -} :: (b -> a) -> b -> b
As one can see, our implementations act as the required functions on their domain, but we narrowed the domains down.
If we specify (<*>) const (<*>) to the reader, we get exactly the function you wrote down as curry . uncurry - id for functions.
Another workalike for curry . uncurry is ($):
f $ x = f x
($) f x = f x
($) f = f
($) = id
The function you found is very interesting - it might be a good exercise to look for other workalikes (I don't know whether there are any other notable ones out there).
I have two simple examples:
1) xt function (what is this?)
Prelude> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
Prelude> :{
Prelude| f::Int->Int
Prelude| f x = x
Prelude| :}
Prelude> xt = fmap f // ?
Prelude> :t xt
xt :: Functor f => f Int -> f Int
Prelude> xt (+2) 1
3
2) xq function (via composition)
Prelude> :{
Prelude| return x = [x]
Prelude| :}
Prelude> xq = return . f
Prelude> :t xq
xq :: Int -> [Int]
Prelude> :t return
return :: a -> [a]
xq function I get through composition return(f(x)). But what does that mean: fmap f and what is difference?
The Functor instance for (->) r defines fmap to be function composition:
fmap f g = f . g
Thus, xt (+2) == fmap f (+2) == f . (+2) == (+2) (since f is the identity function for Int). Applied to 1, you get the observed answer 3.
fmap is the function defined by the Functor type class:
class Functor f where
fmap :: (a -> b) -> f a -> f b
It takes a function as its argument and returns a new function "lifted" into the functor in question. The exact definition is supplied by the Functor instance. Above is the definition for the function functor; here for reference are some simpler ones for lists and Maybe:
instance Functor [] where
fmap = map
instance Functor Maybe where
fmap f Nothing = Nothing
fmap f (Just x) = Just (f x)
> fmap (+1) [1,2,3]
[2,3,4]
> fmap (+1) Nothing
Nothing
> fmap (+1) (Just 3)
Just 4
Since you can think of functors as boxes containing one or more values, the intuition for the function functor is that a function is a box containing the result of applying the function to its argument. That is, (+2) is a box that contains some value plus 2. (F)mapping a function on that box provides a box that contains the result of applying f to the result of the original function, i.e, produces a function that is the composition of f with the original function.
Both xq = return . f and xt = fmap f can be eta-expanded:
xq x = (return . f) x = return (f x) = return x
Now it can be eta-contracted:
xq = return
The second is
xt y = fmap f y = fmap (\x -> x) y = fmap id y = id y = y
fmap has type :: Functor f => (a -> b) -> f a -> f b so fmap f has type :: Functor f => f Int -> f Int, because f :: Int -> Int. From its type we see that fmap f is a function, expecting an Int, and producing an Int.
Since f x = x for Ints by definition, it means that f = id for Ints, where id is a predefined function defined just the same way as f is (but in general, for any type).
Then by Functor laws (and that's all we need to know about "Functors" here), fmap id = id and so xt y = y, in other words it's also id - but only for Ints,
xt = id :: Int -> Int
Naturally, xt (+2) = id (+2) = (+2).
Addendum: for something to be a "Functor" means that it can be substituted for f in
fmap id (x :: f a) = x
(fmap g . fmap h) = fmap (g . h)
so that the expressions involved make sense (i.e. are well formed, i.e. have a type), and the above equations hold (they are in fact the two "Functor laws").
I am trying to convert the following Haskell code to point free style, to no avail.
bar f g xs = filter f (map g xs )
I'm new to Haskell and any help would be great.
Converting to pointfree style can be done entirely mechanically, though it's hard without being comfortable with the fundamentals of Haskell syntax like left-associative function application and x + y being the same as (+) x y. I will assume you are comfortable with Haskell syntax; if not, I suggest going through the first few chapters of LYAH first.
You need the following combinators, which are in the standard library. I have also given their standard names from combinator calculus.
id :: a -> a -- I
const :: a -> b -> a -- K
(.) :: (b -> c) -> (a -> b) -> (a -> c) -- B
flip :: (a -> b -> c) -> (b -> a -> c) -- C
(<*>) :: (a -> b -> c) -> (a -> b) -> (a -> c) -- S
Work with one parameter at a time. Move parameters on the left to lambdas on the right, e.g.
f x y = Z
becomes
f = \x -> \y -> Z
I like to do this one argument at a time rather than all at once, it just looks cleaner.
Then eliminate the lambda you just created according to the following rules. I will use lowercase letters for literal variables, uppercase letters to denote more complex expressions.
If you have \x -> x, replace with id
If you have \x -> A, where A is any expression in which x does not occur, replace with const A
If you have \x -> A x, where x does not occur in A, replace with A. This is known as "eta contraction".
If you have \x -> A B, then
If x occurs in both A and B, replace with (\x -> A) <*> (\x -> B).
If x occurs in just A, replace with flip (\x -> A) B
If x occurs in just B, replace with A . (\x -> B),
If x does not occur in either A or B, well, there's another rule we should have used already.
And then work inward, eliminating the lambdas that you created. Lets work with this example:
f x y z = foo z (bar x y)
-- Move parameter to lambda:
f x y = \z -> foo z (bar x y)
-- Remember that application is left-associative, so this is the same as
f x y = \z -> (foo z) (bar x y)
-- z appears on the left and not on the right, use flip
f x y = flip (\z -> foo z) (bar x y)
-- Use rule (3)
f x y = flip foo (bar x y)
-- Next parameter
f x = \y -> flip foo (bar x y)
-- Application is left-associative
f x = \y -> (flip foo) (bar x y)
-- y occurs on the right but not the left, use (.)
f x = flip foo . (\y -> bar x y)
-- Use rule 3
f x = flip foo . bar x
-- Next parameter
f = \x -> flip foo . bar x
-- We need to rewrite this operator into normal application style
f = \x -> (.) (flip foo) (bar x)
-- Application is left-associative
f = \x -> ((.) (flip foo)) (bar x)
-- x appears on the right but not the left, use (.)
f = ((.) (flip foo)) . (\x -> bar x)
-- use rule (3)
f = ((.) (flip foo)) . bar
-- Redundant parentheses
f = (.) (flip foo) . bar
There you go, now try it on yours! There is not really any cleverness involved in deciding which rule to use: use any rule that applies and you will make progress.
Both of the existing answers don't really answer your specific question in a way that's elucidating: one is "here are the rules, work it out for yourself" and the other is "here is the answer, no information about how the rules generate it."
The first three steps are really easy and consist in removing a common x from something of the form h x = f (g x) by writing h = f . g. Essentially it's saying "if you can write the thing in the form a $ b $ c $ ... $ y $ z and you want to remove the z, change all the dollars to dots, a . b . c . ... . y:
bar f g xs = filter f (map g xs)
= filter f $ (map g xs)
= filter f $ map g $ xs -- because a $ b $ c == a $ (b $ c).
bar f g = filter f . map g
= (filter f .) (map g)
= (filter f .) $ map $ g
bar f = (filter f .) . map
So this last f is the only tricky part, and it's tricky because the f is not at the "end" of the expression. But looking at it, we see that this is a function section (. map) applied to the rest of the expression:
bar f = (.) (filter f) . map
bar f = (. map) $ (.) $ filter $ f
bar = (. map) . (.) . filter
and that's how you reduce an expression when you don't have complicated things like f x x and the like appearing in it. In general there is a function flip f x y = f y x which "flips arguments"; you can always use that to move the f to the other side. Here we have flip (.) map . (.) . filter if you include the explicit flip call.
I asked lambdabot, a robot who hangs out on various Haskell IRC channels, to automatically work out the point-free equivalent. The command is #pl (pointless).
10:41 <frase> #pl bar f g xs = filter f (map g xs )
10:41 <lambdabot> bar = (. map) . (.) . filter
The point free version of bar is:
bar = (. map) . (.) . filter
This is arguably less comprehensible than the original (non-point-free) code. Use your good judgement when deciding whether to use point-free style on a case-by-case basis.
Finally, if you don't care for IRC there are web-based point-free
converters such as pointfree.io, the pointfree command line program, and other tools.
Here is the problem, i need to write the well known twice function
(twice= \x-> \x-> x)
but this time using (.) composition function like (.) f g.
I don't know how to solve it, cause I thought at the beginning to do like:
(.) f g = (\x -> f (g x))
with (g = f) so it would be like this
(.) f f = (\x -> f (f x))
but I have a
"Conflicting definitions for `f'"
running on GHCI
So, any suggestions ?
I don't know how you got anything other than a parse input from this:
(.) f f = (\x -> f (f x))
but the definition you gave: twice = \x -> \x -> x has nothing to do with using something "twice" - indeed if you plug in some values:
twice a b
= (\x -> \x -> x) a b
= (\x -> (\x -> x)) a b -- (rename the inner x)
= (\x -> (\y -> y)) a b
= ((\x -> (\y -> y)) a) b
= (\y -> y) b
= b
and indeed GHCi will tell you the same:
> let twice = \x -> \x -> x
> :t twice
twice :: t -> t1 -> t1
> twice "a" "b"
"b"
Now I guess you want something like this:
let twice f x = f (f x)
for example:
> let twice f x = f (f x)
> twice (+1) 5
7
as you can see twice (+1) adds 2 (or twice one).
Now how can you do this using (.)? - Well your intuition was wright:
> let twice f = f . f
> twice (+1) 5
7
concerning a module
As you asked for a module - this compiles (and loads into GHCi) fine on my system(s):
module Twice where
twice :: (a->a) -> a -> a
twice f = f . f
remark:
this only works if you include (.) from the prelude (or GHC.Base) - I suspect that you got some kind of excercise that hid the prelude - in this case you have to define (.) for yourself first (most likely another excercise)
if you need to implement it yourself:
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) g f x = g (f x)
I am working through the 20 Intermediate Haskell Exercises at the moment, which is quite a fun exercise. It involves implementing various instances of the typeclasses Functor and Monad (and functions that takes Functors and Monads as arguments) but with cute names like Furry and Misty to disguise what we're doing (makes for some interesting code).
I've been trying to do some of this in a point-free style, and I wondered if there's a general scheme for turning a point-ful (?) definition into a point-free definition. For example, here is the typeclass for Misty:
class Misty m where
unicorn :: a -> m a
banana :: (a -> m b) -> m a -> m b
(the functions unicorn and banana are return and >>=, in case it's not obvious) and here's my implementation of apple (equivalent to flip ap):
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple x f = banana (\g -> banana (unicorn . g) x) f
Later parts of the exercises have you implement versions of liftM, liftM2 etc. Here are my solutions:
appleTurnover :: (Misty m) => m (a -> b) -> m a -> m b
appleTurnover = flip apple
banana1 :: (Misty m) => (a -> b) -> m a -> m b
banana1 = appleTurnover . unicorn
banana2 :: (Misty m) => (a -> b -> c) -> m a -> m b -> m c
banana2 f = appleTurnover . banana1 f
banana3 :: (Misty m) => (a -> b -> c -> d) -> m a -> m b -> m c -> m d
banana3 f x = appleTurnover . banana2 f x
banana4 :: (Misty m) => (a -> b -> c -> d -> e) -> m a -> m b -> m c -> m d -> m e
banana4 f x y = appleTurnover . banana3 f x y
Now, banana1 (equivalent to liftM or fmap) I was able to implement in pointfree style, by a suitable definition of appleTurnover. But with the other three functions I've had to use parameters.
My question is: is there a recipe for turning definitions like these into point-free definitions?
As demonstrated by the pointfree utility, it's possible to do any such conversion automatically. However, the result is more often obfuscated than improved. If one's goal is to enhance legibility rather than destroy it, then the first goal should be to identify why an expression has a particular structure, find a suitable abstraction, and build things up that way.
The simplest structure is simply chaining things together in a linear pipeline, which is plain function composition. This gets us pretty far just on its own, but as you noticed it doesn't handle everything.
One generalization is to functions with additional arguments, which can be built up incrementally. Here's one example: Define onResult = (. (.)). Now, applying onResult n times to an initial value of id gives you function composition with the result of an n-ary function. So we can define comp2 = onResult (.), and then write comp2 not (&&) to define a NAND operation.
Another generalization--which encompasses the above, really--is to define operators that apply a function to a component of a larger value. An example here would be first and second in Control.Arrow, which work on 2-tuples. Conal Elliott's Semantic Editor Combinators are based on this approach.
A slightly different case is when you have a multi-argument function on some type b, and a function a -> b, and need to combine them into a multi-argument function using a. For the common case of 2-ary functions, the module Data.Function provides the on combinator, which you can use to write expressions like compare `on` fst to compare 2-tuples on their first elements.
It's a trickier issue when a single argument is used more than once, but there are meaningful recurring patterns here that can also be extracted. A common case here is applying multiple functions to a single argument, then collecting the results with another function. This happens to correspond to the Applicative instance for functions, which lets us write expressions like (&&) <$> (> 3) <*> (< 9) to check if a number falls in a given range.
The important thing, if you want to use any of this in actual code, is to think about what the expression means and how that's reflected in the structure. If you do that, and then refactor it into pointfree style using meaningful combinators, you'll often make the intent of the code clearer than it would otherwise be, unlike the typical output of pointfree.
Yes! One of the tricks is to write your dots in prefix notation rather than infix. Then you should be able to find new things that look like function composition. Here's an example:
banana2 f = appleTurnover . banana1 f
= (.) appleTurnover (banana1 f)
= ((.) appleTurnOver) . banana1 $ f
banana2 = (appleTurnover .) . banana1
The source code for the pointfree utility contains more, but this one handles a lot of cases.
banana4 f x y = appleTurnover . banana3 f x y
= (.) appleTurnover ((banana3 f x) y)
= ((.) appleTurnover) . (banana3 f x) $ y
banana4 f x = ((.) appleTurnover) . (banana3 f x)
= (.) ((.) appleTurnover) (banana3 f x)
= ((.) ((.) appleTurnover)) ((banana3 f) x)
= ((.) ((.) appleTurnover)) . (banana3 f) $ x
banana4 f = ((.) ((.) appleTurnover)) . (banana3 f)
= (.) ((.) ((.) appleTurnover)) (banana3 f)
= ((.) ((.) ((.) appleTurnover))) (banana3 f)
= ((.) ((.) ((.) appleTurnover))) . banana3 $ f
banana4 = ((.) ((.) ((.) appleTurnover))) . banana3
= (((appleTurnover .) .) .) . banana3
I use the following term rewrite system:
\x -> f x ------> f
f y x ----------> flip f x y
\x -> f (g x) --> f . g
It is incomplete (read why in books about combinatory logic), but it's enough:
Here is banana2:
banana2 f = appleTurnover . banana1 f
Rewrite as a lambda:
banana2 = \f -> appleTurnover . banana1 f
Write (.) in prefix style:
banana2 = \f -> (.) appleTurnover (banana1 f)
Note that
banana2 = \f -> ((.) appleTurnover) (banana1 f)
So rule 3 can be applied. f is (.) appleTurnover and g is banana:
banana2 = ((.) appleTurnover) . banana1
There is a pointfree package which takes a Haskell function definition and attempts to re-write it in a pointfree style. I'd suggest experimenting with it to get new ideas. See this page for more details; the package is available here.
Since pointfree style is combinators style, just apply known combinators definitions, reading them backwards to make the substitution:
B f g x = f (g x) -- (.) , <$> for ((->) a)
C f x y = f y x -- flip
K x y = x -- const
I x = x -- id
S f g x = f x (g x) -- <*> , ap for ((->) a)
W f x = f x x -- join
(f >>= g) x = g (f x) x
(f =<< g) x = f (g x) x
At times liftMx, liftAx, sequence, sequenceA can simplify things. I'd also consider foldr, unfoldr, iterate, until etc. as basic combinators.
Often, using operator sections helps too:
op a b = (a `op` b) = (`op` b) a = (a `op`) b
Some patterns can become familiar and so, used directly:
((f .) . g) x y = f (g x y)
((. f) . g) x y = g x (f y)
(((f .) .) . g) x y z = (f .) (g x y) z = f (g x y z)
(((. f) .) . g) x y z = (. f) (g x y) z = g x y (f z)
etc.