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

发布于 2024-10-25 03:09:02 字数 450 浏览 0 评论 0原文

假设我在模块 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

明月夜 2024-11-01 03:09:02

总之,答案是启用模板 haskell 并使用 '''

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

如果您的类型派生 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 提取类型信息是唯一的方法。请特别参阅 reifyInfohttp://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 ''

{-# 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.

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 than 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. See reify and Info particularly: http://hackage.haskell.org/packages/archive/template-haskell/2.5.0.0/doc/html/Language-Haskell-TH.html

乖乖 2024-11-01 03:09:02

您不能将 theMagic 定义为函数(因为它需要类型参数),但您可以接近。

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

You can't define theMagic as a function (since it would need a type argument), but you can get close.

import Data.Typeable
...
putStrLn $ show $ typeOf (undefined :: MyType)
如果没结果 2024-11-01 03:09:02

您可以为此使用代理

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

You can use a Proxy for this:

Prelude> import Data.Typeable
Prelude Data.Typeable> show $ typeRep (Proxy :: Proxy [Int])
"[Int]"
夜未央樱花落 2024-11-01 03:09:02

标准 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文