How to get the type as a String in Haskell?
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.开发者_Go百科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.
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
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)
You can use a Proxy
for this:
Prelude> import Data.Typeable
Prelude Data.Typeable> show $ typeRep (Proxy :: Proxy [Int])
"[Int]"
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.
精彩评论