Y コンビネータ (fixpoint のことを Y コンビネータと呼びます。)

data X = PsiInv (X -> (Int -> Int))

psi :: X -> (X -> (Int -> Int))
psi (PsiInv f) = f

fixpoint :: ((Int -> Int) -> (Int -> Int)) -> (Int -> Int)
fixpoint g = let h y = g (\x -> psi y y x) in
h (PsiInv h)

f :: (Int -> Int) -> (Int -> Int)
f g n = if n==0 then 1
else n * g(n-1)

factorial :: Int -> Int
factorial = fixpoint f
-- factorial 10 == 3628800