我们都知道:t
中的ghci
给出了表达式的类型:
Prelude> :t [1..]
[1..] :: (Enum t, Num t) => [t]
我需要的是相当于haskell脚本中的:t
(我称之为typeStr
):
main = putStrLn $ typeStr [1..]
可以在屏幕上打印(Enum t, Num t) => [t]
之类的内容。
这可能吗?
答案 0 :(得分:5)
是的,有几种方法。
<强> 1。使用动态类型
对于单形类型的简单情况,您可以使用Typeable实例:
Data.Dynamic> typeOf [1..]
[Integer]
<强> 2。使用运行时评估
然而,为了正确地做到这一点 - 获得多态值的类型 - 你需要完整的GHC类型检查器。例如。通过ghc-api库及其漂亮的包装器hint:
Language.Haskell.Interpreter> runInterpreter $ typeOf "[1..]"
Right "(P.Enum t, P.Num t) => [t]"
使用动态调用的完整GHC类型检查器的正确推断类型。
答案 1 :(得分:3)
是的,只要类型是Data.Typeable
的实例:
import Data.Typeable
typeStr :: Typeable a => a -> String
typeStr a = show $ typeOf a
我认为你不会得到最普遍的类型,因为参数将是特定类型。例如,typeStr [1..]
在ghci中产生[Integer]
。
答案 2 :(得分:1)
简短回答:不。
Haskell通常不允许你编写直到运行时类型未知的表达式,因此首先不需要运行时类型查找。
话虽如此, 方式可以进行动态类型化,并且可能支持打印类型签名......但这可能不是您想要做的事情。
另一种可能性是使用Template Haskell在编译时查找类型签名。我不知道是否有人已为此编写代码......