您如何在编译时访问有关值的 运行 时间类型的信息?

How do you access information about the value's run-time type at compile time?

如何在编译时访问有关值的 运行 时间类型的信息?

例如,如果您想查询有关特定属性的 运行 时间类型或使用动态类型。

第四次编辑:这个问题的另一种措辞可以是:“"How do you access information about the value's compile-time type at run-time? For example, if you want to interrogate at run-time about specific properties or use dynamic typing."

对我来说,这两种表述是等价的,因为据我所知,在纯函数式语言中,所有关于类型的信息在编译时都是已知的。这可能是造成混淆的原因 - 我在考虑 "run-time information accessible at compile time" 而大多数人都在考虑 "compile-time information acessible at run-time" :)

您可能混淆了类型系统和 RTTI/reflection 的概念。 Haskell 不需要像 typeid()dynamic_cast()is 运算符,因为您不能传递与函数期望类型不同的参数(好吧,你可以,但它是通过类型级作弊和不安全的方式完成的。

因为 Haskell 是强静态类型的,传递值的代码通常不需要查看值就知道它是什么类型。

因此至少在 GHC 编译器中,Haskell 是通过 "type erasure" 实现的。这意味着类型值的运行时表示通常不包含有关其类型的信息。这使得表示更加高效和紧凑。

同样在某些情况下,尤其是在使用 newtypes 时,它允许在两种类型之间进行转换而绝对没有开销 - 因为两种类型的运行时表示完全 一样,两段代码可以共享这个值,把它当成不同的类型。

这并不意味着您不能在运行时获取有关值类型的编译时信息。但是你必须要求它包含在运行时信息中,在 (GHC) Haskell 中的方法是通过 Data.Typeable module.[=19 中的类型类 Typeable =]

  • 此类型类为您提供数据类型构造函数的名称、模块名称和包名称以及任何类型参数。
  • 如果您有两个值在编译时不是同一类型,但它们都有 Typeable 约束,您可以在运行时检查它们的类型是否相等。
  • 使用 cast,您还可以在两种类型恰好相等的情况下转换值。
  • 但是请注意,所有涉及的类型都必须是单态的。你不能 使用它来比较多态的类型 functions/values 而无需首先将它们专门化为具体的单态类型。

还有类型 Dynamic(在 Data.Dynamic 中)允许您封装和传递未知的值,但是 Typeable 类型。