puede hacerlo de esta manera:.
import Data.Typeable
getStaticType :: Typeable a => a -> String
getStaticType = show . typeOf
Tenga en cuenta que el tipo debe ser una instancia de Typeable
. Puede derivar Typeable
automáticamente utilizando la extensión de idioma Haskell DeriveDataTypeable
y ... deriving (Typeable, ...)
.
También tenga en cuenta que los tipos polimórficos no se pueden identificar de esta manera; siempre debe llamar a una función con un tipo específico , de modo que nunca pueda obtener esa información de tipo polimórfico que obtiene en GHCi con el código compilado Haskell.
La forma en que GHCi lo hace es que utiliza la API de GHC para analizar un árbol de sintaxis abstracta (AST) de Haskell intermediario que contiene información de tipo. GHCi no tiene el mismo entorno restringido que su programa compilado típico de Haskell; puede hacer muchas cosas para obtener más información sobre su entorno.
Con TemplateHaskell, puede hacerlo así; En primer lugar, crear este módulo:
module TypeOf where
import Control.Monad
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
getStaticType :: Name -> Q Exp
getStaticType = lift <=< fmap pprint . reify
Luego, en un módulo diferente (muy importante), puede hacer lo siguiente:
salidas
{-# LANGUAGE TemplateHaskell #-}
import TypeOf
main = putStrLn $(getStaticType 'zipWith)
Este programa:
GHC.List.zipWith :: forall a_0 b_1 c_2 . (a_0 -> b_1 -> c_2) ->
[a_0] -> [b_1] -> [c_2]
Puede usar una mejor impresora que la función pprint
; Eche un vistazo al módulo Language.Haskell.TH.Ppr
.
el uso es para el código de auto-documentación y registro. Es una lástima que no sea posible, parece que sería trivial implementarlo como una "función mágica" en el compilador, que ya tiene toda la información. – drwowe
TBH, Haskell es bastante fuerte "anti-magia". –
@drwowe es correcto, sería bastante fácil de implementar en un compilador. Sería una especie de función de tiempo de compilación como * sizeof * en C. – Ingo