开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜