Reputation: 2738
Is there a function one can call within a Haskell program that does what :t
does interactively? Or is this something Haskell cannot do since it's type would not make sense. What about a function that returned the name of the type as a String?
Upvotes: 14
Views: 20678
Reputation: 152707
typeOf
is the canonical way to do this. Beware that it doesn't (can't) handle polymorphism as well as tools outside the language can.
Data.Typeable> typeOf ()
()
Data.Typeable> typeOf "hi"
[Char]
Data.Typeable> typeOf 3 -- hmmm....
Integer
Data.Typeable> typeOf id -- HMMMMMM...
<interactive>:4:1: error:
• No instance for (Typeable a0) arising from a use of ‘typeOf’
• In the expression: typeOf id
In an equation for ‘it’: it = typeOf id
Upvotes: 17
Reputation: 548
For those who like me stumble into here looking for a way to name a type variable in a pattern-matched existential type (for instance to use it in a visible type application), it's a little obvious in hindsight, but you need ScopedTypeVariables and to specify an in-line type signature, e.g.
data Existential where
Existential :: Typeable a => a -> Existential
typeInExistential :: Existential -> TypeRep
typeInExistential (Existential (x :: a)) = typeRep (Proxy @a)
(this is a slightly convoluted example, but you get the idea)
Upvotes: 1
Reputation: 54
This works well with monomorphic arrow types:
λ> typeOf (id @Int)
Int -> Int
Upvotes: 1
Reputation: 9238
The question can be understood twofold:
can a polymorphic function inquire the concrete type it is called with. The other questions describe how it could be done.
can we get to runtime statically known information about a binding. This is what actually the :t
does. There are ways to get it:
a. to just print it during compilation, you could enable PartialSignatures extension, and add to arbitrary expression signature :: _
, then its type will be printed during compilation.
b. to actually get the type as a data for runtime handling, you could use TemplateHaskell extension and function reify
from it.
Upvotes: 2
Reputation: 25763
This is not something that Haskell programmers commonly want or need. So if you want this feature, you are doing something unusual. This can be because you are a beginner and still getting used to program in Haskell (in that case – what are you trying to achieve?). Or you are beyond beginner and want to experiment with unusual feature (in that case – read on).
If you are looking for a function that takes a String
, interprets it as a Haskell term type-checks it and gives you its string, then you can embedd the Haskell compiler in your program. Look at the hint library.
If you are in a polymorphic context and want, maybe for debugging, know the type that some type variable a
is bound to, then the Typeable
type class can provide you this information: show (typeOf x)
gives you the concrete type of the value referenced by the term x
. You may have to add Typeable a
constraints to your polymorphic function.
Upvotes: 11