我们都知道:t
inghci
给出了表达式的类型:
Prelude> :t [1..]
[1..] :: (Enum t, Num t) => [t]
我需要的是等效:t
于haskell脚本(我称之为typeStr
):
main = putStrLn $ typeStr [1..]
可以(Enum t, Num t) => [t]
在屏幕上打印类似的东西。
那可能吗?
是的,有几种方法。
1.使用动态类型
对于单态类型的简单情况,您可以使用 Typeable 实例:
Data.Dynamic> typeOf [1..]
[Integer]
2.使用运行时评估
但是,要正确执行此操作 - 获取多态值的类型 - 您将需要完整的 GHC 类型检查器。例如,通过 ghc-api 库及其漂亮的包装器提示:
Language.Haskell.Interpreter> runInterpreter $ typeOf "[1..]"
Right "(P.Enum t, P.Num t) => [t]"
哪个是使用完整 GHC 类型检查器正确推断的类型,动态调用。
是的,您可以,只要类型是以下实例Data.Typeable
:
import Data.Typeable
typeStr :: Typeable a => a -> String
typeStr a = show $ typeOf a
但是,我认为您不会获得最通用的类型,因为参数将是特定类型。例如, ghci 中的typeStr [1..]
产量[Integer]
。
简短的回答:没有。
Haskell 通常不允许您编写直到运行时才知道类型的表达式,因此首先不需要运行时类型查找。
话虽如此,有一些方法可以进行动态类型,并且可能支持打印类型签名......但这可能根本不是你想要做的。
另一种可能性是使用 Template Haskell 在编译时查找类型签名。我不知道是否有人已经为此编写了代码...