2

我们都知道:tinghci给出了表达式的类型:

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

我需要的是等效:t于haskell脚本(我称之为typeStr):

main = putStrLn $ typeStr [1..]

可以(Enum t, Num t) => [t]在屏幕上打印类似的东西。

那可能吗?

4

3 回答 3

5

是的,有几种方法。

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 类型检查器正确推断的类型,动态调用。

于 2013-02-24T15:21:11.883 回答
3

是的,您可以,只要类型是以下实例Data.Typeable

import Data.Typeable
typeStr :: Typeable a => a -> String
typeStr a = show $ typeOf a

但是,我认为您不会获得最通用的类​​型,因为参数将是特定类型。例如, ghci 中的typeStr [1..]产量[Integer]

于 2013-02-24T15:13:26.373 回答
1

简短的回答:没有。

Haskell 通常不允许您编写直到运行时才知道类型的表达式,因此首先不需要运行时类型查找。

话虽如此,有一些方法可以进行动态类型,并且可能支持打印类型签名......但这可能根本不是你想要做的。

另一种可能性是使用 Template Haskell 在编译时查找类型签名。我不知道是否有人已经为此编写了代码...

于 2013-02-24T14:54:25.330 回答