假设我在模块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等等,这不是我想要的。
答案 0 :(得分:9)
总之,答案是启用模板haskell并使用'和''
{-# LANGUAGE TemplateHaskell #-}
main = do
putStrLn $ show 'read
如果您的类型派生Typeable
(ghc可以自动执行),那么您只需从typeOf
调用Data.Typeable
即可获得可展示的代表。
如果您想获取某些多态函数的类型,Hackage上的多类型包允许您这样做:http://hackage.haskell.org/packages/archive/polytypeable/0.1.0.0/doc/html/Data-PolyTypeable.html
这是一种疯狂的类型级别的东西,由Oleg编写并由Lennart打包,请注意。它有......怪癖。最明显的是它无法给你(我也无法想象任何事情可以坦率地说)类约束上下文。因此,show会被赋予a -> String
而不是forall a. Show a => a -> String
的类型。
如果你需要更多,并且只对编译时做某些事情感到满意,那么使用模板haskell直接从ghc中提取类型信息是唯一的方法。请参阅reify
和Info
,特别是:http://hackage.haskell.org/packages/archive/template-haskell/2.5.0.0/doc/html/Language-Haskell-TH.html
答案 1 :(得分:2)
您可以为此使用Proxy
Prelude> import Data.Typeable
Prelude Data.Typeable> show $ typeRep (Proxy :: Proxy [Int])
"[Int]"
答案 2 :(得分:1)
你不能将魔法定义为一个函数(因为它需要一个类型参数),但你可以接近。
import Data.Typeable
...
putStrLn $ show $ typeOf (undefined :: MyType)
答案 3 :(得分:0)
标准Haskell不支持类型名称;仅适用于deriving Show
的仿函数名称。您可以使用Template Haskell将类型名称作为字符串获取。