Holes in GHC

Iavor Diatchki iavor.diatchki at gmail.com
Wed Jan 25 17:50:57 CET 2012


Hello,

On Wed, Jan 25, 2012 at 7:21 AM, Thijs Alkemade <thijsalkemade at gmail.com> wrote:
> Also, we have a confusing problem when type checking a module. Above,
> we showed the result of ":t map __ __" in ghci. However, if we put "f
> = map __ __" in a module, we get:
>
> tcRnModule: [(f.hs:1:9-10, GHC.Prim.Any * -> b),
> (f.hs:1:12-13, [GHC.Prim.Any *])]
>
> If I read GHC.Prim.Any * as forall a. a, then this is not correct: the
> GHC.Prim.Any * in both holes should have the same type. We assume it
> shows up because the type that should be there does not occur in the
> type signature of f (as it's just [b]), but so far we've been unable
> to figure out why this behavior is different in interactive mode. Does
> someone have an idea about what to do to avoid the introduction of
> these GHC.Prim.Any * types?

The type `Any` is just an ordinary monomorphic type, (e.g., like
Int`).  It is used to stand in for types that "do not matter" and may
be thought of a special case of defaulting (i.e. resolving type
ambiguity be selecting concrete types).  How it is used  is probably
best illustrated with an example (you've found one, but I'll use a
slightly simpler one).  Consider the expression `null []`.  It clearly
has the type Bool, because `null` takes a list and returns a Bool, and
`[]` is a list.  However, there is nothing that forces the list
elements to be of one type or another, so we cannot infer the full
type of `[]`---in some sense, the expression `null []` is of type
`forall a. Bool` where `a` is the type of the list elements.
Inferring this type would not be useful because we have no way to
specify what the `a` should be, and furthermore, it does not matter!
So, whenever GHC infers a type `forall a. P => t` where `a` does not
appear in `P` or `t`, it knows that the `a` does not matter, so t
simply defaults it to `Any`.


> Examples:
>
> *Main> :t [__, ()]
> tcRnExpr2: [(<interactive>:1:2-3, ())]
> [__, ()] :: [()]
>
> *Main> :t map __ __
> tcRnExpr2: [(<interactive>:1:5-6, a0 -> b), (<interactive>:1:8-9, [a0])]
> map __ __ :: [b]
>
> Any feedback on this design would be appreciated. We would like to
> know if this is something that could be considered to be added to GHC,
> and what your requirements for that are.

I was just wondering if you could get the same behavior by using
`undefined`?  For example,

    :t [undefined, ()]
    [()]

-Iavor



More information about the Glasgow-haskell-users mailing list