In Haskell, we have Data.Function.on:
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
(.*.) `on` f = \x y -> f x .*. f y
In Clojure, I want to be able to define, for example,
an anagram predicate as follows:
(defn anagram? [word other-word]
(and (not= word other-word)
((on = sort) word other-word)))
It's trivial to implement:
(defn on [g f] (fn [x y] (g (f x) (f y))))
But is there any built-in function
that accomplishes the same goal?
I can't seem to find one.
No, there is no built-in that does what you are looking for. If you are going to implement it, though, I think you can afford to be a little more generic, since Clojure has vararg support and lacks currying:
(defn on
([f g]
(fn [x y]
(f (g x)
(g y))))
([f g & args]
(on f #(apply g % args))))
This lets you write something like
(defn same-parity? [x y]
((on = mod 2) x y))
which of course is easy in Haskell too, as
sameParity :: (Integral a) => a -> a -> Bool
sameParity = (==) `on` (`mod` 2)
But in Clojure the partial application of mod is a little trickier, so it's customary to provide equivalent functionality via &args if you can.
Related
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.
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)
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.
Is it possible to write the Y Combinator in Haskell?
It seems like it would have an infinitely recursive type.
Y :: f -> b -> c
where f :: (f -> b -> c)
or something. Even a simple slightly factored factorial
factMaker _ 0 = 1
factMaker fn n = n * ((fn fn) (n -1)
{- to be called as
(factMaker factMaker) 5
-}
fails with "Occurs check: cannot construct the infinite type: t = t -> t2 -> t1"
(The Y combinator looks like this
(define Y
(lambda (X)
((lambda (procedure)
(X (lambda (arg) ((procedure procedure) arg))))
(lambda (procedure)
(X (lambda (arg) ((procedure procedure) arg)))))))
in scheme)
Or, more succinctly as
(λ (f) ((λ (x) (f (λ (a) ((x x) a))))
(λ (x) (f (λ (a) ((x x) a))))))
For the applicative order
And
(λ (f) ((λ (x) (f (x x)))
(λ (x) (f (x x)))))
Which is just a eta contraction away for the lazy version.
If you prefer short variable names.
Here's a non-recursive definition of the y-combinator in haskell:
newtype Mu a = Mu (Mu a -> a)
y f = (\h -> h $ Mu h) (\x -> f . (\(Mu g) -> g) x $ x)
hat tip
The Y combinator can't be typed using Hindley-Milner types, the polymorphic lambda calculus on which Haskell's type system is based. You can prove this by appeal to the rules of the type system.
I don't know if it's possible to type the Y combinator by giving it a higher-rank type. It would surprise me, but I don't have a proof that it's not possible. (The key would be to identify a suitably polymorphic type for the lambda-bound x.)
If you want a fixed-point operator in Haskell, you can define one very easily because in Haskell, let-binding has fixed-point semantics:
fix :: (a -> a) -> a
fix f = f (fix f)
You can use this in the usual way to define functions and even some finite or infinite data structures.
It is also possible to use functions on recursive types to implement fixed points.
If you're interested in programming with fixed points, you want to read Bruce McAdam's technical report That About Wraps it Up.
The canonical definition of the Y combinator is as follows:
y = \f -> (\x -> f (x x)) (\x -> f (x x))
But it doesn't type check in Haskell because of the x x, since it would require an infinite type:
x :: a -> b -- x is a function
x :: a -- x is applied to x
--------------------------------
a = a -> b -- infinite type
If the type system were to allow such recursive types, it would make type checking undecidable (prone to infinite loops).
But the Y combinator will work if you force it to typecheck, e.g. by using unsafeCoerce :: a -> b:
import Unsafe.Coerce
y :: (a -> a) -> a
y = \f -> (\x -> f (unsafeCoerce x x)) (\x -> f (unsafeCoerce x x))
main = putStrLn $ y ("circular reasoning works because " ++)
This is unsafe (obviously). rampion's answer demonstrates a safer way to write a fixpoint combinator in Haskell without using recursion.
Oh
this wiki page and
This Stack Overflow answer seem to answer my question.
I will write up more of an explanation later.
Now, I've found something interesting about that Mu type. Consider S = Mu Bool.
data S = S (S -> Bool)
If one treats S as a set and that equals sign as isomorphism, then the equation becomes
S ⇋ S -> Bool ⇋ Powerset(S)
So S is the set of sets that are isomorphic to their powerset!
But we know from Cantor's diagonal argument that the cardinality of Powerset(S) is always strictly greater than the cardinality of S, so they are never isomorphic.
I think this is why you can now define a fixed point operator, even though you can't without one.
Just to make rampion's code more readable:
-- Mu :: (Mu a -> a) -> Mu a
newtype Mu a = Mu (Mu a -> a)
w :: (Mu a -> a) -> a
w h = h (Mu h)
y :: (a -> a) -> a
y f = w (\(Mu x) -> f (w x))
-- y f = f . y f
in which w stands for the omega combinator w = \x -> x x, and y stands for the y combinator y = \f -> w . (f w).
From time to time I stumble over the problem that I want to express "please use the last argument twice", e.g. in order to write pointfree style or to avoid a lambda. E.g.
sqr x = x * x
could be written as
sqr = doubleArgs (*) where
doubleArgs f x = f x x
Or consider this slightly more complicated function (taken from this question):
ins x xs = zipWith (\ a b -> a ++ (x:b)) (inits xs) (tails xs)
I could write this code pointfree if there were a function like this:
ins x = dup (zipWith (\ a b -> a ++ (x:b))) inits tails where
dup f f1 f2 x = f (f1 x) (f2 x)
But as I can't find something like doubleArgs or dup in Hoogle, so I guess that I might miss a trick or idiom here.
From Control.Monad:
join :: (Monad m) -> m (m a) -> m a
join m = m >>= id
instance Monad ((->) r) where
return = const
m >>= f = \x -> f (m x) x
Expanding:
join :: (a -> a -> b) -> (a -> b)
join f = f >>= id
= \x -> id (f x) x
= \x -> f x x
So, yeah, Control.Monad.join.
Oh, and for your pointfree example, have you tried using applicative notation (from Control.Applicative):
ins x = zipWith (\a b -> a ++ (x:b)) <$> inits <*> tails
(I also don't know why people are so fond of a ++ (x:b) instead of a ++ [x] ++ b... it's not faster -- the inliner will take care of it -- and the latter is so much more symmetrical! Oh well)
What you call 'doubleArgs' is more often called dup - it is the W combinator (called warbler in To Mock a Mockingbird) - "the elementary duplicator".
What you call 'dup' is actually the 'starling-prime' combinator.
Haskell has a fairly small "combinator basis" see Data.Function, plus some Applicative and Monadic operations add more "standard" combinators by virtue of the function instances for Applicative and Monad (<*> from Applicative is the S - starling combinator for the functional instance, liftA2 & liftM2 are starling-prime). There doesn't seem to be much enthusiasm in the community for expanding Data.Function, so whilst combinators are good fun, pragmatically I've come to prefer long-hand in situations where a combinator is not directly available.
Here is another solution for the second part of my question: Arrows!
import Control.Arrow
ins x = inits &&& tails >>> second (map (x:)) >>> uncurry (zipWith (++))
The &&& ("fanout") distributes an argument to two functions and returns the pair of the results. >>> ("and then") reverses the function application order, which allows to have a chain of operations from left to right. second works only on the second part of a pair. Of course you need an uncurry at the end to feed the pair in a function expecting two arguments.