v217
v217

Reputation: 805

What is the nearest equivalent of :type in ghci in a ghc source file?

If I want to compare types or just print type information in a Haskell source file, what options do I have?

Upvotes: 3

Views: 139

Answers (2)

Ben
Ben

Reputation: 71400

A handy trick I've recently discovered is to use typed holes in combination with asTypeOf1.

If you have code that does compile, and you want to know what the type of an expression within it is, replacing that expression with a hole sometimes messes things up, as in:

           -- what is the type of this part, I wonder?
f xs = 3 * length xs

Replacing length xs with a _ reports:

foo.hs:1:12: Warning:
    Found hole ‘_’ with type: a
    Where: ‘a’ is a rigid type variable bound by
               the inferred type of f :: t -> a at foo.hs:1:1

length xs is certainly not of type a!

But if you use asTypeOf, you can leave the length xs there and insert a hole which has to have the same type as it:

f xs = 3 * (length xs `asTypeOf` _)

Now we get:

foo.hs:1:34: Warning:
    Found hole ‘_’ with type: Int

Much better.


1 asTypeOf is exactly the same as const, in that it returns its first argument and completely ignores its second. However its type forces the second argument to be the same as the first; it's designed to be written infix with backticks.

It's designed for when you have an a sub-expression that's too polymorphic and GHC complains about ambiguous type variables; you could use an inline type declaration, but sometimes that's impossible without the ScopedTypeVariables extension. If you have another value that is the correct type, you can use asTypeOf to "select" the appropriate case from the polymorphic expression, without changing the value returned by the expression.

My use of it here is "backwards" from the intended case; I want the thing on the left to constrain type of the (ignored) hole on the right, rather than the other way around.

Upvotes: 4

chi
chi

Reputation: 116139

Typed holes!

foo x =  length [x] + _

Compiling with GHC or loading into GHCi will give:

Found hole ‘_’ with type: Int
Relevant bindings include
  x :: a
  foo :: a -> Int

Upvotes: 7

Related Questions