Haskell中是否有一个函数返回其参数的类型(或显示类型的字符串)?

时间:2018-05-14 18:19:48

标签: haskell

是否有一个可以在Haskell程序中调用的函数,该函数以:t的形式交互执行?或者这是Haskell无法做到的事情,因为它的类型没有意义。将类型名称作为String返回的函数怎么办?

5 个答案:

答案 0 :(得分:10)

typeOf是执行此操作的规范方法。请注意,它不能(不能)处理多态性以及语言之外的工具。

Data.Typeable> typeOf ()
()
Data.Typeable> typeOf "hi"
[Char]
Data.Typeable> typeOf 3 -- hmmm....
Integer
Data.Typeable> typeOf id -- HMMMMMM...
<interactive>:4:1: error:
    • No instance for (Typeable a0) arising from a use of ‘typeOf’
    • In the expression: typeOf id
      In an equation for ‘it’: it = typeOf id

答案 1 :(得分:8)

这不是Haskell程序员通常想要或需要的东西。所以,如果你想要这个功能,你就会做一些不寻常的事情。这可能是因为你是初学者并且仍然习惯于在Haskell中编程(在这种情况下 - 你想要实现什么?)。或者你不是初学者,想要尝试不寻常的功能(在这种情况下 - 阅读)。

  • 如果您正在寻找一个带有String的函数,将其解释为Haskell术语类型 - 检查它并为您提供其字符串,那么您可以在程序中嵌入Haskell编译器。查看hint库。

  • 如果您处于多态上下文中并希望(可能是为了调试)知道某个类型变量a绑定的类型,那么Typeable类型类可以为您提供此信息:show (typeOf x)为您提供术语x引用的值的具体类型。您可能必须为您的多态函数添加Typeable a约束。

答案 2 :(得分:1)

这个问题可以理解为两个方面:

  1. 可以通过多态函数查询调用它的具体类型。其他问题描述了如何做到这一点。

  2. 我们可以获得有关绑定的运行时静态已知信息。这就是:t的实际情况。有办法得到它:

  3. 一个。要在编译期间打印它,您可以启用PartialSignatures扩展,并添加到任意表达式签名:: _,然后在编译期间打印它的类型。

    湾要实际获取类型作为运行时处理的数据,您可以使用TemplateHaskell扩展和函数reify

答案 3 :(得分:0)

这对于单态箭头类型非常适用:

λ> typeOf (id @Int)
Int -> Int

答案 4 :(得分:0)

对于那些像我一样偶然来到这里寻找一种方法来命名模式匹配的存在类型中的类型变量的人(例如在可见类型应用程序中使用它),事后看来这有点明显,但你需要ScopedTypeVariables 并指定内嵌类型签名,例如

data Existential where
  Existential :: Typeable a => a -> Existential

typeInExistential :: Existential -> TypeRep
typeInExistential (Existential (x :: a)) = typeRep (Proxy @a)

(这是一个稍微复杂的例子,但你懂的)