你可以这样做:
import Data.Typeable
getStaticType :: Typeable a => a -> String
getStaticType = show . typeOf
请注意,类型必须是 的实例Typeable
。您可以Typeable
使用DeriveDataTypeable
Haskell 语言扩展和... deriving (Typeable, ...)
.
另请注意,不能以这种方式识别多态类型;您必须始终调用具有特定类型的函数,因此您永远无法获得在 GHCi 中使用已编译的 Haskell 代码获得的多态类型信息。
GHCi 的做法是使用 GHC API 来分析包含类型信息的中间 Haskell 抽象语法树 (AST)。GHCi 与典型的已编译 Haskell 程序没有相同的受限环境;它可以做很多事情来了解有关其环境的更多信息。
使用 TemplateHaskell,您可以这样做;首先,创建这个模块:
module TypeOf where
import Control.Monad
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
getStaticType :: Name -> Q Exp
getStaticType = lift <=< fmap pprint . reify
然后,在不同的模块(非常重要)中,您可以执行以下操作:
{-# LANGUAGE TemplateHaskell #-}
import TypeOf
main = putStrLn $(getStaticType 'zipWith)
该程序输出:
GHC.List.zipWith :: forall a_0 b_1 c_2 . (a_0 -> b_1 -> c_2) ->
[a_0] -> [b_1] -> [c_2]
您可以使用比该pprint
功能更好的漂亮打印机;看看Language.Haskell.TH.Ppr
模块。