简体   繁体   English

如何在 Haskell 中将类型作为字符串获取?

[英]How to get the type as a String in Haskell?

Let's say I have a type MyType defined in module My.Module.假设我在模块 My.Module 中定义了一个类型 MyType。 I want to have the String "My.Module.MyType" (or something like that).我想要字符串“My.Module.MyType”(或类似的东西)。 If I just type the String directly, I might have a typo, and if the module or type name changes, I'd like to know at compile time.如果我直接输入字符串,我可能会打错字,如果模块或类型名称发生变化,我想在编译时知道。

Ah, there appears there might be confusion about what I'm asking.啊,我问的问题似乎有些混乱。 Please look at the question carefully.请仔细看问题。 Given the code:鉴于代码:

module My.Module
type MyType = Int
data MyType2 = MyConstructor2 Int
main = do
  putStrLn $ theMagic MyType
  putStrLn $ theMagic MyType2

The output I want is:我想要的输出是:

My.Module.MyType
My.Module.MyType2

I'm looking for the type name, not the type definition.我正在寻找类型名称,而不是类型定义。 typeOf would output Int and such, that's not what I want. typeOf 会输出 Int 等,这不是我想要的。

In summary, the answer is to enable template haskell and use ' and ''总之,答案是启用模板haskell并使用'''

{-# LANGUAGE TemplateHaskell #-}
main = do
  putStrLn $ show 'read

If your type derives Typeable (which ghc can do automatically) then you can just call typeOf from Data.Typeable to get a showable representation.如果您的类型派生Typeable (ghc 可以自动执行),那么您只需从Data.Typeable调用typeOf即可获得可显示的表示。

If you want to get types of certain polymorphic functions, the polytypeable package on Hackage allows you to do so: http://hackage.haskell.org/packages/archive/polytypeable/0.1.0.0/doc/html/Data-PolyTypeable.html如果你想获得某些多态函数的类型,Hackage 上的 polytypeable 包允许你这样做: http ://hackage.haskell.org/packages/archive/polytypeable/0.1.0.0/doc/html/Data-PolyTypeable 。 html

This is a sort of insane type-level thing written by Oleg and packaged by Lennart, mind you.请注意,这是一种由 Oleg 编写并由 Lennart 打包的疯狂类型级别的东西。 And it has.. quirks.它有..怪癖。 The most glaring is that it can't give you (nor can I imagine how anything could, frankly) class constraint contexts.最明显的是它不能给你(坦率地说,我也无法想象有什么东西可以)类约束上下文。 So show will be given a type of a -> String rather than forall a. Show a => a -> String所以 show 会被赋予一个类型a -> String而不是forall a. Show a => a -> String forall a. Show a => a -> String . forall a. Show a => a -> String

If you need more than that, and are satisfied with doing certain things only at compile time, then using template haskell to extract type information directly from ghc is the only way to go.如果您需要的不止这些,并且满足于只在编译时做某些事情,那么使用模板 haskell 直接从 ghc 中提取类型信息是唯一的出路。 See reify and Info particularly: http://hackage.haskell.org/packages/archive/template-haskell/2.5.0.0/doc/html/Language-Haskell-TH.html特别参见reifyInfohttp : //hackage.haskell.org/packages/archive/template-haskell/2.5.0.0/doc/html/Language-Haskell-TH.html

You can't define theMagic as a function (since it would need a type argument), but you can get close.你不能将 theMagic 定义为一个函数(因为它需要一个类型参数),但你可以接近。

import Data.Typeable
...
putStrLn $ show $ typeOf (undefined :: MyType)

You can use a Proxy for this:您可以为此使用Proxy

Prelude> import Data.Typeable
Prelude Data.Typeable> show $ typeRep (Proxy :: Proxy [Int])
"[Int]"

Standard Haskell does not support this for type names;标准 Haskell 不支持此类型名称; only for functor names with deriving Show .仅适用于deriving Show函子名称。 You may be able to get type names as strings using Template Haskell .您可以使用Template Haskell将类型名称作为字符串获取。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM