haskell metaprogramming template-haskell

haskell - Función para el nombre de la función de salida



metaprogramming template-haskell (4)

No sé para qué lo necesitas, pero tal vez una solución simplista sea suficiente. Al igual que:

data NamedFunction a b = NamedFunction { name :: String, apply :: a -> b } timesTwo :: NamedFunction Int Int timesTwo = NamedFunction "timesTwo" (/x -> 2 * x)

que puedes usar de la siguiente manera:

ghci> timesTwo `apply` 7 14 ghci> name timesTwo "timesTwo"

Luego puede escribir su propia versión de (.) :

-- contrast (.) :: (b -> c) -> (a -> b) -> (a -> c) compose :: NamedFunction b c -> NamedFunction a b -> NamedFunction a c compose (NamedFunction n1 f1) (NamedFunction n2 f2) = NamedFunction (n1++ " . " ++ n2) (f1 . f2)

En ghci:

ghci> let f = timesTwo `compose` timesTwo in (f `apply` 7, name f) (28,"timesTwo . timesTwo")

Tendrá que volver a implementar sus propias versiones de map , filter , etc., y es probable que se encuentre con otros problemas más adelante, pero tal vez esto es todo lo que necesita ...

¿Es posible en Haskell implementar una función que devuelva su propio nombre de función?

Un posible tipo podría ser (a -> b) -> String .


¿Desea una función que toma un argumento de función y devuelve el nombre de la variable de sitio de definición que corresponde al nombre de esa función?

Esto no es posible sin meta-programación, que generalmente es una señal de que estás haciendo algo mal :). Pero suponiendo que no lo estés, una forma de lograr algo en la dirección correcta es a través de Template Haskell , que puede obtener nombres únicos (cómo el compilador nombra cosas). P.ej

Prelude Language.Haskell.TH> :set -XTemplateHaskell Prelude Language.Haskell.TH> let f x y = x + y Prelude Language.Haskell.TH> $( stringE . show =<< reify ''f ) "VarI f_1627394057 (ForallT [PlainTV a_1627394063] [ClassP GHC.Num.Num [VarT a_1627394063]] (AppT (AppT ArrowT (VarT a_1627394063)) (AppT (AppT ArrowT (VarT a_1627394063)) (VarT a_1627394063)))) Nothing (Fixity 9 InfixL)"

Y ahora sabemos mucho sobre la variable. Para que pueda jugar juegos pasando un nombre a la función (a través de ''f) en lugar de f sí mismo.

Sin embargo, ciertamente se encuentra en el mundo de la reflexión y la metaprogramación, por lo que ayudaría saber más acerca de lo que está tratando de hacer.


¿Me estoy perdiendo de algo? Esta función devuelve su propio nombre de función.

Prelude> let myNameIs::(a->b) -> String; myNameIs f = "myNameIs" Prelude> :type myNameIs myNameIs :: (a -> b) -> String Prelude> myNameIs myNameIs "myNameIs"


Para aclarar algo mencionado en la publicación de dons: ninguna función tiene nombres en Haskell. Hay enlaces que pueden unir funciones, pero si tuviera esa función (llámalo getName ) a medida que buscas, ¿qué esperarías que esto devuelva?

let f x = x g = f h = f in getName g == getName h