ejemplos - funciones en haskell
Haskell: ¿Función para determinar la aridad de las funciones? (6)
En Haskell, cada "función" toma exactamente un argumento. Lo que parece una función de "múltiples argumentos" es en realidad una función que toma un argumento y devuelve otra función que toma el resto de los argumentos. Así que en ese sentido todas las funciones tienen aridad 1.
¿Es posible escribir una función arity :: a -> Integer
para determinar la aridad de funciones arbitrarias, de modo que
> arity map
2
> arity foldr
3
> arity id
1
> arity "hello"
0
?
Es fácil con OverlappingInstances
:
{-# LANGUAGE FlexibleInstances, OverlappingInstances #-}
class Arity f where
arity :: f -> Int
instance Arity x where
arity _ = 0
instance Arity f => Arity ((->) a f) where
arity f = 1 + arity (f undefined)
Actualizaciones encontrado problema. Debe especificar el tipo no polimórfico para funciones polimórficas:
arity (foldr :: (a -> Int -> Int) -> Int -> [a] -> Int)
No sé cómo resolver esto todavía.
Upd2, como comentó Sjoerd Visscher a continuación, "debe especificar un tipo no polimórfico, ya que la respuesta depende del tipo que elija".
No es posible con Haskell estándar. Puede ser posible usar IncoherentInstances o una extensión similar.
Pero ¿por qué quieres hacer esto? No puede preguntar a una función cuántos argumentos espera y luego usar este conocimiento para darle exactamente esa cantidad de argumentos. (A menos que esté utilizando Template Haskell, en cuyo caso, sí, espero que sea posible en tiempo de compilación. ¿Está utilizando Template Haskell?)
¿Cuál es tu problema real que estás tratando de resolver?
Qué tal esto:
arity :: a -> Int
arity (b->c) = 1 + arity (c)
arity _ = 0
Sí, se puede hacer muy, muy fácilmente:
arity :: (a -> b) -> Int
arity = const 1
Justificación: si es una función, puede aplicarla exactamente a 1 argumento. Tenga en cuenta que la sintaxis de haskell hace que sea imposible aplicar a 0, 2 o más argumentos, ya que fab
es realmente (fa) b
, es decir, no se f applied to a and b
, pero (f applied to a) applied to b
. El resultado puede ser, por supuesto, otra función que se puede aplicar de nuevo, y así sucesivamente.
Suena estúpido, pero no es más que la verdad.
Si id
tiene arity 1, ¿no debería id x
tener arity 0? Pero, por ejemplo, id map
es idéntico a map
, que tendría arity 2 en tu ejemplo.
¿Tienen las siguientes funciones la misma aridad?
f1 = (+)
f2 = (/x y -> x + y)
f3 x y = x + y
Creo que tu noción de "aridad" no está bien definida ...