Seems a function should have a name to be recursive(in order to call itself), so how does a lambda function be recursive?
I searched wikipedia and it says this could be done by a "Y-combinator". I don't have much math theory backgroup, it just tell me that "Y-combinator" is discovered by Haskell himself. Called "fix" keyword in Haskell language, I tried:
Prelude> let fact = fix (\f n -> if n == 0 then 1 else n * (f (n-1)))
<interactive>:17:12: Not in scope: ‘fix’
Seems failed, but how to use "fix" keyword to do what I expected?
fix is not a keyword, it is a function defined in the Data.Function module. Therefore, to use it, you must import that module.
import Data.Function
or in GHCi:
:m Data.Function
fix is defined as:
fix :: (a -> a) -> a
fix f = let x = f x in x
so it expands into f (f (f (f ...))) i.e. an infinite sequence of nested applications of the input function f to some parameter x.
You can give your lambda function a top-level definition e.g.
factF f n = if n == 0 then 1 else n * f (n - 1)
or equivalently:
factF :: (Int -> Int) -> (Int -> Int)
factF f = \n -> if n == 0 then 1 else n * f (n - 1)
you can provide this function to fix to obtain a function (Int -> Int) i.e.
fact :: (Int -> Int)
fact = fix factF
if you expand this definition you get
factF (factF (factF (factF ...)))
=> \n -> if n == 0 then 1 else (factF (factF (factF ...)))
due to laziness, the repeated applications of factF are only evaluated if n /= 0 so the above function applied to 0 will evaluate immediately to 1.
You can see in this expansion that factF is being provided as an argument to itself which it then applies to smaller version of n. Since factN is the same as your lambda function, the same thing is happening there - the parameter f inside the lambda is the lambda itself which it can then call recursively.
Related
I am trying to learn Haskell, this is my very first approach at functional programming. I'm having some trouble creating a function that takes a number as input and prints that number one by one recursively, until 0.
printDescending n = if n > 0
then printDescending n - 1 return n
else return n - 1
I want to be able to do printDescending 20 and have it output 20, 19, 18...2, 1, 0. But I'm getting this error:
> • Non type-variable argument
> in the constraint: Num ((a -> m a) -> a1 -> m1 a1)
> (Use FlexibleContexts to permit this)
> • When checking the inferred type
> printDescending :: forall (m :: * -> *) a (m1 :: * -> *) a1.
> (Ord a1, Num ((a -> m a) -> a1 -> m1 a1), Num (m1 a1), Num a1,
> Monad m1, Monad m) =>
> a1 -> m1 a1 Failed, modules loaded: none.
I think it may be my syntax. Anyone have some insight?
You have shown:
printDescending n = if n > 0
then printDescending n - 1 return n
else return n - 1
Lets first look at how this is parsed:
printDescending n = if n > 0
then (printDescending n) - (1 return n)
else (return n) - 1
Probably not what you intended, huh? Notice the infix operators, such as - bind less tightly than function application. Also see how 'return' is not special - it's also just function application. Finally, you didn't actually include a call to any sort of print command so no matter what language you are using I wouldn't expect this to function.
Fixing these issues, let's first provide a type signature (which is somewhat like a function prototype in C):
printDescending :: Int -> IO ()
So printDecending accepts one argument, an Int, and does some IO. the () is called "unit" and for the first lesson of a programmer who knows C you should be able to mentally think of that as void and be OK.
Now how about the body? Well your if statement was fine:
printDescending n =
if n > 0
then ...
else...
The else statement was a little weird. Even fixing the parsing, why would you want 0-1? Let's just return unit:
printDescending n =
if n > 0
then ...
else return ()
Now for the then branch you want two things really. 1. print the value 2. recursively call printDecending on the next smallest value. There is one bit of notation, do, that we'll use to sequence two IO operations but beyond that these two tasks translate to commands directly:
printDescending n =
if n > 0
then do print n
printDescending (n - 1)
else return ()
Now lets do one more step. Since this isn't C/Java/etc and is a functional language then people will expect a declarative style. To that end, let's declare printDescending using guards instead of an if statement:
printDescending n
| n > 0 = do print n
printDescending (n-1)
| otherwise = return ()
Alternatives
Now I'm going to present some alternatives, just for exemplification.
If you don't care about negative values then we could just terminate on zero with something like:
printDescending 0 = return ()
printDescending n =
do print n
printDescending (n-1)
Or we can use list comprehension to build a list of the values then perform print on each element of the list. We can do this with forM_ (see also the more idiomatic mapM_) which executes an operation on each element of the list and throws away the results, returning unit.
printDescending n = forM_ [n,n-1..1] print
Finally, if you want to have more rapid exchanges then consider joining the #haskell channel on irc.freenode.net. There's a great group there and it's where many of the Haskell programmers I know got their start.
In addition to Thomas' detailed answer, I get the feeling that the following is what you were going for:
printDescending :: Integer -> IO ()
printDescending n = do
print n
if n > 0
then printDescending (n - 1)
else return ()
Admittedly, the return () may seem strange at first.
A more functional approach might be something like this:
printDescending :: Integer -> IO ()
printDescending n = mapM_ print [n, (n-1) .. 0]
A quick tip: I'd recommend adding the function signature (if you know what it is) as it will help guide the compiler's error messages.
What is the GHC equivalent of OCaml's -rectypes for allowing recursive types? I don't see one in the documentation. Is it a hidden feature?
There isn't one unfortunately, all recursion must go through a data type. However, if you're willing to put up with a bit of headache you can still write recursive types pretty easily.
newtype RecArr b a = RecArr {unArr :: RecArr b a -> b}
unfold = unArr
fold = RecArr
Now we can fold and unfold our RecArr to unfold our recursion to our hearts content. This is a little painful because it's manual, but completely workable. As a demonstration, here's the y combinator written using fold and unfold.
y f = (\x -> f (unfold x x)) $ fold (\x -> f (unfold x x))
factorial f n = if n == 0 then 1 else n * f (n-1)
main = print (y factorial 5) -- prints 120
There is none. All recursion has to go through nominal types. That is, you have to define a data type.
I recently learned about Data.Function.fix, and now I want to apply it everywhere. For example, whenever I see a recursive function I want to "fix" it. So basically my question is where and when should I use it.
To make it more specific:
1) Suppose I have the following code for factorization of n:
f n = f' n primes
where
f' n (p:ps) = ...
-- if p^2<=n: returns (p,k):f' (n `div` p^k) ps for k = maximum power of p in n
-- if n<=1: returns []
-- otherwise: returns [(n,1)]
If I rewrite it in terms of fix, will I gain something? Lose something? Is it possible, that by rewriting an explicit recursion into fix-version I will resolve or vice versa create a stack overflow?
2) When dealing with lists, there are several solutions: recursion/fix, foldr/foldl/foldl', and probably something else. Is there any general guide/advice on when to use each? For example, would you rewrite the above code using foldr over the infinite list of primes?
There are, probably, other important questions not covered here. Any additional comments related to the usage of fix are welcome as well.
One thing that can be gained by writing in an explicitly fixed form is that the recursion is left "open".
factOpen :: (Integer -> Integer) -> Integer -> Integer
factOpen recur 0 = 1
factOpen recur n = n * recur (pred n)
We can use fix to get regular fact back
fact :: Integer -> Integer
fact = fix factOpen
This works because fix effectively passes a function itself as its first argument. By leaving the recursion open, however, we can modify which function gets "passed back". The best example of using this property is to use something like memoFix from the memoize package.
factM :: Integer -> Integer
factM = memoFix factOpen
And now factM has built-in memoization.
Effectively, we have that open-style recursion requires us impute the recursive bit as a first-order thing. Recursive bindings are one way that Haskell allows for recursion at the language level, but we can build other, more specialized forms.
I'd like to mention another usage of fix; suppose you have a simple language consisting of addition, negative, and integer literals. Perhaps you have written a parser which takes a String and outputs a Tree:
data Tree = Leaf String | Node String [Tree]
parse :: String -> Tree
-- parse "-(1+2)" == Node "Neg" [Node "Add" [Node "Lit" [Leaf "1"], Node "Lit" [Leaf "2"]]]
Now you would like to evaluate your tree to a single integer:
fromTree (Node "Lit" [Leaf n]) = case reads n of {[(x,"")] -> Just x; _ -> Nothing}
fromTree (Node "Neg" [e]) = liftM negate (fromTree e)
fromTree (Node "Add" [e1,e2]) = liftM2 (+) (fromTree e1) (fromTree e2)
Suppose someone else decides to extend the language; they want to add multiplication. They will have to have access to the original source code. They could try the following:
fromTree' (Node "Mul" [e1, e2]) = ...
fromTree' e = fromTree e
But then Mul can only appear once, at the top level of the expression, since the call to fromTree will not be aware of the Node "Mul" case. Tree "Neg" [Tree "Mul" a b] will not work, since the original fromTree has no pattern for "Mul". However, if the same function is written using fix:
fromTreeExt :: (Tree -> Maybe Int) -> (Tree -> Maybe Int)
fromTreeExt self (Node "Neg" [e]) = liftM negate (self e)
fromTreeExt .... -- other cases
fromTree = fix fromTreeExt
Then extending the language is possible:
fromTreeExt' self (Node "Mul" [e1, e2]) = ...
fromTreeExt' self e = fromTreeExt self e
fromTree' = fix fromTreeExt'
Now, the extended fromTree' will evaluate the tree properly, since self in fromTreeExt' refers to the entire function, including the "Mul" case.
This approach is used here (the above example is a closely adapted version of the usage in the paper).
Beware the difference between _Y f = f (_Y f) (recursion, value--copying) and fix f = x where x = f x (corecursion, reference--sharing).
Haskell's let and where bindings are recursive: same name on the LHS and RHS refer to the same entity. The reference is shared.
In the definition of _Y there's no sharing (unless a compiler performs an aggressive optimization of common subexpressions elimination). This means it describes recursion, where repetition is achieved by application of a copy of an original, like in a classic metaphor of a recursive function creating its own copies. Corecursion, on the other hand, relies on sharing, on referring to same entity.
An example, primes calculated by
2 : _Y ((3:) . gaps 5 . _U . map (\p-> [p*p, p*p+2*p..]))
-- gaps 5 == ([5,7..] \\)
-- _U == sort . concat
either reusing its own output (with fix, let g = ((3:)...) ; ps = g ps in 2 : ps) or creating separate primes supply for itself (with _Y, let g () = ((3:)...) (g ()) in 2 : g ()).
See also:
double stream feed to prevent unneeded memoization?
How to implement an efficient infinite generator of prime numbers in Python?
Or, with the usual example of factorial function,
gen rec n = n<2 -> 1 ; n * rec (n-1) -- "if" notation
facrec = _Y gen
facrec 4 = gen (_Y gen) 4
= let {rec=_Y gen} in (\n-> ...) 4
= let {rec=_Y gen} in (4<2 -> 1 ; 4*rec 3)
= 4*_Y gen 3
= 4*gen (_Y gen) 3
= 4*let {rec2=_Y gen} in (3<2 -> 1 ; 3*rec2 2)
= 4*3*_Y gen 2 -- (_Y gen) recalculated
.....
fac = fix gen
fac 4 = (let f = gen f in f) 4
= (let f = (let {rec=f} in (\n-> ...)) in f) 4
= let {rec=f} in (4<2 -> 1 ; 4*rec 3) -- f binding is created
= 4*f 3
= 4*let {rec=f} in (3<2 -> 1 ; 3*rec 2)
= 4*3*f 2 -- f binding is reused
.....
1) fix is just a function, it improves your code when you use some recursion. It makes your code prettier.For example usage visit: Haskell Wikibook - Fix and recursion.
2) You know what does foldr? Seems like foldr isn't useful in factorization (or i didn't understand what are you mean in that).
Here is a prime factorization without fix:
fact xs = map (\x->takeWhile (\y->y/=[]) x) . map (\x->factIt x) $ xs
where factIt n = map (\x->getFact x n []) [2..n]
getFact i n xs
| n `mod` i == 0 = getFact i (div n i) xs++[i]
| otherwise = xs
and with fix(this exactly works like the previous):
fact xs = map (\x->takeWhile (\y->y/=[]) x) . map (\x->getfact x) $ xs
where getfact n = map (\x->defact x n) [2..n]
defact i n =
fix (\rec j k xs->if(mod k j == 0)then (rec j (div k j) xs++[j]) else xs ) i n []
This isn't pretty because in this case fix isn't a good choice(but there is always somebody who can write it better).
I am not sure if this is good programming practice, but I would like to know if one can define a recursive function using the lambda expression.
This is an artificial example I made up: So one can defined the factorial function in Haskell recursively as follows
factorial :: Integer -> Integer
factorial 1 = 1
factorial (n + 1) = (n + 1) * factorial n
Now, I want a function f such that f n = (factorial n) + 1. Rather than using a name for factorial n (i.e. defining it before hand), I want to define f where factorial n is given a lambda expression within the definition of f. Can I use a recursive lambda definition in f in place of using the name factorial?
The canonical way to do recursion with pure lambda expressions is to use a fixpoint combinator, which is a function with the property
fixpoint f x = f (fixpoint f) x
If we assume that such a combinator exists, we can write the recursive function as
factorial = fixpoint (\ff n -> if n == 1 then 1 else n * ff(n-1))
The only problem is that fixpoint itself is still recursive. In the pure lambda calculus, there are ways to create fixpoint combinators that consist only of lambdas, for example the classical "Y combinator":
fixpoint f = (\x -> f (x x)) (\x -> f (x x))
But we still have problems, because this definition is not well-typed according to Haskell -- and it can be proved that there is no way to write a well-typed fixpoint combinator using only lambdas and function applications. It can be done by use of an auxiliary data type to shoehorn in some type recursion:
data Paradox a = Self (Paradox a -> a)
fixpoint f = let half (Self twin) = f (twin (Self twin))
in half (Self half)
(Note that if the injections and projections from the singleton data type are removed, this is exactly the Y combinator!)
Yes, using the fixed-point function fix:
fact :: Int -> Int
fact = fix (\f n -> if n == 0 then 1 else n * (f (n-1)))
Basically, it doesn't have a name, since it's a lambda expression, so you take the function in as an argument. Fix applies the function to itself "infinitely" many times:
fix f = f (fix f)
and is defined in Data.Function.
Why do we use lambda's instead of let in?
Prelude> (let fib n = if n == 1 then 1 else n * fib(n-1) in fib ) 4
24
Owen is spot on with the fix function
Prelude> fix f = f (fix f)
Prelude> fix (\f n -> if n == 0 then 1 else n * f (n - 1)) 6
720
The nameless Lambda function is self terminating even if fix is not.
Owen's fix function beats the fix function typically used in Haskell which is
fix :: (a -> a) -> a
fix f = let {x = f x} in x
Both allow anonymous recursive lambda functions
I was a bit confused by the documentation for fix (although I think I understand what it's supposed to do now), so I looked at the source code. That left me more confused:
fix :: (a -> a) -> a
fix f = let x = f x in x
How exactly does this return a fixed point?
I decided to try it out at the command line:
Prelude Data.Function> fix id
...
And it hangs there. Now to be fair, this is on my old macbook which is kind of slow. However, this function can't be too computationally expensive since anything passed in to id gives that same thing back (not to mention that it's eating up no CPU time). What am I doing wrong?
You are doing nothing wrong. fix id is an infinite loop.
When we say that fix returns the least fixed point of a function, we mean that in the domain theory sense. So fix (\x -> 2*x-1) is not going to return 1, because although 1 is a fixed point of that function, it is not the least one in the domain ordering.
I can't describe the domain ordering in a mere paragraph or two, so I will refer you to the domain theory link above. It is an excellent tutorial, easy to read, and quite enlightening. I highly recommend it.
For the view from 10,000 feet, fix is a higher-order function which encodes the idea of recursion. If you have the expression:
let x = 1:x in x
Which results in the infinite list [1,1..], you could say the same thing using fix:
fix (\x -> 1:x)
(Or simply fix (1:)), which says find me a fixed point of the (1:) function, IOW a value x such that x = 1:x... just like we defined above. As you can see from the definition, fix is nothing more than this idea -- recursion encapsulated into a function.
It is a truly general concept of recursion as well -- you can write any recursive function this way, including functions that use polymorphic recursion. So for example the typical fibonacci function:
fib n = if n < 2 then n else fib (n-1) + fib (n-2)
Can be written using fix this way:
fib = fix (\f -> \n -> if n < 2 then n else f (n-1) + f (n-2))
Exercise: expand the definition of fix to show that these two definitions of fib are equivalent.
But for a full understanding, read about domain theory. It's really cool stuff.
I don't claim to understand this at all, but if this helps anyone...then yippee.
Consider the definition of fix. fix f = let x = f x in x. The mind-boggling part is that x is defined as f x. But think about it for a minute.
x = f x
Since x = f x, then we can substitute the value of x on the right hand side of that, right? So therefore...
x = f . f $ x -- or x = f (f x)
x = f . f . f $ x -- or x = f (f (f x))
x = f . f . f . f . f . f . f . f . f . f . f $ x -- etc.
So the trick is, in order to terminate, f has to generate some sort of structure, so that a later f can pattern match that structure and terminate the recursion, without actually caring about the full "value" of its parameter (?)
Unless, of course, you want to do something like create an infinite list, as luqui illustrated.
TomMD's factorial explanation is good. Fix's type signature is (a -> a) -> a. The type signature for (\recurse d -> if d > 0 then d * (recurse (d-1)) else 1) is (b -> b) -> b -> b, in other words, (b -> b) -> (b -> b). So we can say that a = (b -> b). That way, fix takes our function, which is a -> a, or really, (b -> b) -> (b -> b), and will return a result of type a, in other words, b -> b, in other words, another function!
Wait, I thought it was supposed to return a fixed point...not a function. Well it does, sort of (since functions are data). You can imagine that it gave us the definitive function for finding a factorial. We gave it a function that dind't know how to recurse (hence one of the parameters to it is a function used to recurse), and fix taught it how to recurse.
Remember how I said that f has to generate some sort of structure so that a later f can pattern match and terminate? Well that's not exactly right, I guess. TomMD illustrated how we can expand x to apply the function and step towards the base case. For his function, he used an if/then, and that is what causes termination. After repeated replacements, the in part of the whole definition of fix eventually stops being defined in terms of x and that is when it is computable and complete.
You need a way for the fixpoint to terminate. Expanding your example it's obvious it won't finish:
fix id
--> let x = id x in x
--> id x
--> id (id x)
--> id (id (id x))
--> ...
Here is a real example of me using fix (note I don't use fix often and was probably tired / not worrying about readable code when I wrote this):
(fix (\f h -> if (pred h) then f (mutate h) else h)) q
WTF, you say! Well, yes, but there are a few really useful points here. First of all, your first fix argument should usually be a function which is the 'recurse' case and the second argument is the data on which to act. Here is the same code as a named function:
getQ h
| pred h = getQ (mutate h)
| otherwise = h
If you're still confused then perhaps factorial will be an easier example:
fix (\recurse d -> if d > 0 then d * (recurse (d-1)) else 1) 5 -->* 120
Notice the evaluation:
fix (\recurse d -> if d > 0 then d * (recurse (d-1)) else 1) 3 -->
let x = (\recurse d -> if d > 0 then d * (recurse (d-1)) else 1) x in x 3 -->
let x = ... in (\recurse d -> if d > 0 then d * (recurse (d-1)) else 1) x 3 -->
let x = ... in (\d -> if d > 0 then d * (x (d-1)) else 1) 3
Oh, did you just see that? That x became a function inside our then branch.
let x = ... in if 3 > 0 then 3 * (x (3 - 1)) else 1) -->
let x = ... in 3 * x 2 -->
let x = ... in 3 * (\recurse d -> if d > 0 then d * (recurse (d-1)) else 1) x 2 -->
In the above you need to remember x = f x, hence the two arguments of x 2 at the end instead of just 2.
let x = ... in 3 * (\d -> if d > 0 then d * (x (d-1)) else 1) 2 -->
And I'll stop here!
How I understand it is, it finds a value for the function, such that it outputs the same thing you give it. The catch is, it will always choose undefined (or an infinite loop, in haskell, undefined and infinite loops are the same) or whatever has the most undefineds in it. For example, with id,
λ <*Main Data.Function>: id undefined
*** Exception: Prelude.undefined
As you can see, undefined is a fixed point, so fix will pick that. If you instead do (\x->1:x).
λ <*Main Data.Function>: undefined
*** Exception: Prelude.undefined
λ <*Main Data.Function>: (\x->1:x) undefined
[1*** Exception: Prelude.undefined
So fix can't pick undefined. To make it a bit more connected to infinite loops.
λ <*Main Data.Function>: let y=y in y
^CInterrupted.
λ <*Main Data.Function>: (\x->1:x) (let y=y in y)
[1^CInterrupted.
Again, a slight difference. So what is the fixed point? Let us try repeat 1.
λ <*Main Data.Function>: repeat 1
[1,1,1,1,1,1, and so on
λ <*Main Data.Function>: (\x->1:x) $ repeat 1
[1,1,1,1,1,1, and so on
It is the same! Since this is the only fixed point, fix must settle on it. Sorry fix, no infinite loops or undefined for you.
As others pointed out, fix somehow captures the essence of recursion. Other answers already do a great job at explaining how fix works. So let's take a look from another angle and see how fix can be derived by generalising, starting from a specific problem: we want to implement the factorial function.
Let's first define a non recursive factorial function. We will use it later to "bootstrap" our recursive implementation.
factorial n = product [1..n]
We approximate the factorial function by a sequence of functions: for each natural number n, factorial_n coincides with factorial up to and including n. Clearly factorial_n converges towards factorial for n going towards infinity.
factorial_0 n = if n == 0 then 1 else undefined
factorial_1 n = n * factorial_0(n - 1)
factorial_2 n = n * factorial_1(n - 1)
factorial_3 n = n * factorial_2(n - 1)
...
Instead of writing factorial_n out by hand for every n, we implement a factory function that creates these for us. We do this by factoring the commonalities out and abstracting over the calls to factorial_[n - 1] by making them a parameter to the factory function.
factorialMaker f n = if n == 0 then 1 else n * f(n - 1)
Using this factory, we can create the same converging sequence of functions as above. For each factorial_n we need to pass a function that calculates the factorials up to n - 1. We simply use the factorial_[n - 1] from the previous step.
factorial_0 = factorialMaker undefined
factorial_1 = factorialMaker factorial_0
factorial_2 = factorialMaker factorial_1
factorial_3 = factorialMaker factorial_2
...
If we pass our real factorial function instead, we materialize the limit of the series.
factorial_inf = factorialMaker factorial
But since that limit is the real factorial function we have factorial = factorial_inf and thus
factorial = factorialMaker factorial
Which means that factorial is a fixed-point of factorialMaker.
Finally we derive the function fix, which returns factorial given factorialMaker. We do this by abstracting over factorialMaker and make it an argument to fix. (i.e. f corresponds to factorialMaker and fix f to factorial):
fix f = f (fix f)
Now we find factorial by calculating the fixed-point of factorialMaker.
factorial = fix factorialMaker