将表达式转换为在haskell脚本中描述其类型的字符串?

时间:2013-02-24 14:40:37

标签: haskell ghc ghci

我们都知道:t中的ghci给出了表达式的类型:

Prelude> :t [1..]
[1..] :: (Enum t, Num t) => [t]

我需要的是相当于haskell脚本中的:t(我称之为typeStr):

main = putStrLn $ typeStr [1..]

可以在屏幕上打印(Enum t, Num t) => [t]之类的内容。

这可能吗?

3 个答案:

答案 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在编译时查找类型签名。我不知道是否有人已为此编写代码......