Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a fixed point operator in Haskell?

I recently noticed that I quite often write functions which just iterates another function f until it reaches a fixed point (such that f x == x)

I thought this is a pretty general concept, so I think there might be a built in.

So I was wondering whether there is a built in for this, or something more general?

So I'm basically looking for this:

fixedpoint f x= head . dropWhile(\y->y /= f y) $ iterate f x

I just had trouble googling this, because I only found references to the fix function whenever my search term contained fixed point or something similar.

like image 265
flawr Avatar asked Aug 15 '16 12:08

flawr


People also ask

What is fix Haskell?

fix will find a fixed point of fact' , i.e. the function f such that f == fact' f . But let's expand what this means: f = fact' f = \n -> if n == 0 then 1 else n * f (n-1) All we did was substitute rec for f in the definition of fact' . But this looks exactly like a recursive definition of a factorial function!

What does NS mean in Haskell?

The sequence (n:ns) is a shorthand for head - tail. Quite literally, the first value, the head, is called n and the remained are the other, potentially plural, n s, which is why it is called ns . Haskell has pattern matching.

What is left and right in Haskell?

The Either type is sometimes used to represent a value which is either correct or an error; by convention, the Left constructor is used to hold an error value and the Right constructor is used to hold a correct value (mnemonic: "right" also means "correct").


3 Answers

Just write it yourself. A direct version will be faster than one using dropWhile.

hammer :: Eq a => (a -> a) -> a -> a
hammer f x
  | x' == x = x'
  | otherwise = hammer f x'
  where x' = f x
like image 52
dfeuer Avatar answered Oct 27 '22 13:10

dfeuer


Your function has the signature Eq a => (a -> a) -> a -> a.

Using hoogle to search for that, I don't see any exact matches. The closest match is until

until :: (a -> Bool) -> (a -> a) -> a -> a

base Prelude

until p f yields the result of applying f until p holds.

You could likely use that to write your function but because you need /= you need the Eq constraint.

like image 36
Daenyth Avatar answered Oct 27 '22 12:10

Daenyth


In case you are looking for a build-in because you want a short expression without any auxiliary functions, I can recommend

until=<<((==)=<<) :: Eq a => (a -> a) -> a -> a

Arguably this looks a bit strange, but in fact it is just the point-free equivalent to until (\x -> f x == x) f, using the fact that f (g x) x can be expressed by (f=<<g) x twice.

like image 1
Laikoni Avatar answered Oct 27 '22 12:10

Laikoni