haskell factorial

head haskell



FunciĆ³n factorial incorporada en Haskell (7)

Aunque se usa comúnmente para ejemplos, la función factorial no es tan útil en la práctica. Las cifras crecen muy rápidamente, y la mayoría de los problemas que incluyen la función factorial pueden (y deben) calcularse de formas más eficientes.

Un ejemplo trivial es calcular coeficientes binomiales. Si bien es posible definirlos como

choose n k = factorial n `div` (factorial k * factorial (n-k))

es mucho más eficiente no usar factoriales:

choose n 0 = 1 choose 0 k = 0 choose n k = choose (n-1) (k-1) * n `div` k

Entonces, no, no está incluido en el preludio estándar. Tampoco es la secuencia de Fibonacci, la función de Ackermann u otras muchas funciones que, aunque teóricamente interesantes, no se usan con la suficiente frecuencia en la práctica como para garantizar un lugar en las bibliotecas estándar.

Dicho esto, hay muchas bibliotecas de matemáticas disponibles en Hackage .

Sé que esto suena como una pregunta estúpida, pero aquí está: ¿Hay un factorial incorporado en Haskell?

Google me da tutoriales sobre Haskell explicando cómo puedo implementarlo yo mismo, y no pude encontrar nada en Hoogle. No quiero volver a escribirlo cada vez que lo necesite.

Puedo usar el product [1..n] como reemplazo, pero ¿existe una verdadera función incorporada factorial Int -> Int ?


La mejor implementación de factorial que conozco en Hackage es Math.Combinatorics.Exact.Factorial.factorial en el paquete de exact-combinatorics . Utiliza un algoritmo asintóticamente más rápido que el product [1..n] .

http://hackage.haskell.org/package/exact-combinatorics


No, pero puedes escribir uno fácilmente. Si te preocupa tener que volver a escribir la función cada vez que la necesites, siempre puedes escribirla como parte de un módulo o una biblioteca (dependiendo de qué tan lejos quieras tomar esto, cuántas funciones similares tienes). De esta forma, solo necesita escribirlo una vez y puede incorporarlo rápidamente a cualquier otro proyecto cuando lo necesite.



Si está buscando una expresión lambda, entonces siempre puede usar el fix (/fx -> if x == 0 then 1 else x * (f (x - 1))) clásico fix (/fx -> if x == 0 then 1 else x * (f (x - 1))) .


Usted tiene la función del product que está en el preludio estándar. Combinado con rangos puede obtener una función factorial con un mínimo esfuerzo.

factorial n = product [n, n-1 .. 1] nCr n r = n'' `div` r'' where -- unroll just what you need and nothing more n'' = product [n, n-1 .. n-r+1] r'' = factorial r


fac = product . flip take [1..]