Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In haskell, what exactly is the type of a constructor of an ADT that has no parameters?

Tags:

haskell

Suppose I define a type

data A a = A a | B deriving Show

I know that (B :: A Int) == (B :: A Double) does not typecheck because A Int and A Double are different, unequal types, so I can't apply (==) :: Eq a => a -> a -> Bool

But then I can ask ghci what is show B, and ghci says it is the string "B". What exactly is the type of that B? Is it A Int? Why? And why does ghci not complain that the type of B is ambiguous, given that it can be A a for absolutely any a.

I can similarly ask ghci what is show (B==B), and it says "True", what is the type of both those B's?

When I ask ghci the type of B with :t B, it prints B :: A a, but unless I am confused in the two examples above it must be some specific type without any type parameters. So how do I find out what the type of B in B==B is?

I'm confused a little. Is this described anywhere?

like image 881
Kirill Avatar asked Jan 11 '23 19:01

Kirill


1 Answers

The reason for the behaviour is an ghc extension that is called ExtendedDefaultRules.

Quoting from the link:

However, it is tiresome for the user to have to specify the type, so GHCi extends Haskell's type-defaulting rules (Section 4.3.4 of the Haskell 2010 Report) as follows. The standard rules take each group of constraints (C1 a, C2 a, ..., Cn a) for each type variable a, and defaults the type variable if

  1. The type variable a appears in no other constraints
  2. All the classes Ci are standard.
  3. At least one of the classes Ci is numeric.

At the GHCi prompt, or with GHC if the -XExtendedDefaultRules flag is given, the following additional differences apply:

  • Rule 2 above is relaxed thus: All of the classes Ci are single-parameter type classes.
  • Rule 3 above is relaxed this: At least one of the classes Ci is numeric, or is Show, Eq, or Ord. The unit type () is added to the start of the standard list of types which are tried when doing type defaulting.

So according to these rules, in B == B or show B, () is picked for a.

You can also test this by doing the following at the GHCi prompt:

:set -XNoExtendedDefaultRules
data Foo a = A a | B deriving Eq
B == B

which results in the expected ambiguous type variable a error.

like image 199
bennofs Avatar answered Jan 13 '23 07:01

bennofs