RussAbbott
RussAbbott

Reputation: 2738

Is there a function in Haskell that returns the type of its argument (or a string showing the type)?

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

Answers (5)

Daniel Wagner
Daniel Wagner

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

lierdakil
lierdakil

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

Ilya Rodionov
Ilya Rodionov

Reputation: 54

This works well with monomorphic arrow types:

λ> typeOf (id @Int)
Int -> Int

Upvotes: 1

max630
max630

Reputation: 9238

The question can be understood twofold:

  1. can a polymorphic function inquire the concrete type it is called with. The other questions describe how it could be done.

  2. 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

Joachim Breitner
Joachim Breitner

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

Related Questions