如何在 Haskell 中获取字符串类型?
假设我在模块 My.Module 中定义了一个类型 MyType。我想要字符串“My.Module.MyType”(或类似的东西)。如果我直接输入字符串,我可能会出现拼写错误,如果模块或类型名称发生变化,我想在编译时知道。
啊,看来我问的问题可能有些混乱。请仔细看问题。给定代码:
module My.Module
type MyType = Int
data MyType2 = MyConstructor2 Int
main = do
putStrLn $ theMagic MyType
putStrLn $ theMagic MyType2
我想要的输出是:
My.Module.MyType
My.Module.MyType2
我正在寻找类型名称,而不是类型定义。 typeOf 会输出 Int 等,这不是我想要的。
Let's say I have a type MyType defined in module My.Module. I want to have the String "My.Module.MyType" (or something like that). 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
总之,答案是启用模板 haskell 并使用
'
和''
如果您的类型派生
Typeable
(ghc 可以自动执行),那么您只需从Data.Typeable
调用typeOf
即可获得可显示的表示形式。如果您想获取某些多态函数的类型,Hackage 上的 polytypeable 包允许您这样做:http://hackage.haskell.org/packages/archive/polytypeable/0.1.0.0/doc/html/Data-PolyTypeable.html
这是一个请注意,这是由 Oleg 编写并由 Lennart 打包的疯狂类型级别的东西。它有..怪癖。最明显的是它不能给你(坦率地说,我也无法想象任何东西可以)类约束上下文。因此 show 将被赋予
a ->; 的类型。 String
而不是forall a.显示=>一个->字符串
。如果您需要更多,并且满足于仅在编译时执行某些操作,那么使用模板 haskell 直接从 ghc 提取类型信息是唯一的方法。请特别参阅
reify
和Info
:http://hackage.haskell.org/packages/archive/template-haskell/2.5.0.0/doc/html/Language-Haskell-TH.html< /a>In summary, the answer is to enable template haskell and use
'
and''
If your type derives
Typeable
(which ghc can do automatically) then you can just calltypeOf
fromData.Typeable
to get a showable representation.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
This is a sort of insane type-level thing written by Oleg and packaged by Lennart, mind you. 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 thanforall 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. See
reify
andInfo
particularly: http://hackage.haskell.org/packages/archive/template-haskell/2.5.0.0/doc/html/Language-Haskell-TH.html您不能将 theMagic 定义为函数(因为它需要类型参数),但您可以接近。
You can't define theMagic as a function (since it would need a type argument), but you can get close.
您可以为此使用
代理
:You can use a
Proxy
for this:标准 Haskell 不支持类型名称;仅适用于具有
派生 Show
的函子名称。您可以使用 Template Haskell 获取字符串形式的类型名称。Standard Haskell does not support this for type names; only for functor names with
deriving Show
. You may be able to get type names as strings using Template Haskell.