3
votes

The question

What is the type constructor which generates a concrete type like [(Int,String)]?

The origin of the question

I think this really sounds either like a stupid question or a meaningless riddle. I hope the following convinces you that I'm actually trying to find gaps in my understanding of the basics.

I know that []

  • is a value (an empty list of any type),
  • and it is a (unary) type constructor;

to "visualize" the second aspect, I can just type

> x = [1,2,3] :: [] Int
> :t x
x :: [Int]

which clearly shows that [] applied to the concrete type Int gives another concrete type [Int].

So far so good.

On the other hand, (,) also has two meanings:

  • it is a (binary) type constructor too, which I verify with this
> x = (1,1) :: (,) Int Int
> :t
x :: (Int, Int)
  • but it is also a value constructor:
> (,) 1 "hello"
(1,"hello")

So, if both [] and (,) are type constructors that can originate, among other types, concrete types [Int] and (Int,Char), I wonder what is the type constructor that generates a type like [(Int,Char)].

2
Needs more focus? Really. Enlighten me about why this is the case... :)Enlico
"[] applied to the concrete type Int gives another concrete type [Int]" yes: try GHCi> :k [] in GHCi to see this type's kind attesting to that. use GHCi> :t [] to see that value's type (same with (,), both as a value and as a type -- functions are values too).Will Ness

2 Answers

4
votes

It's not so much a single type constructor as it is a nested type constructor:

λ> x = [(1, 'a')] :: [] ((,) Int Char)
λ> :t x
x :: [(Int, Char)]
2
votes

There is no explicit form of such a type constructor but you can roll your own:

type TupleList f s = [(f, s)]

TupleList is now a type constructor with two argument. If you apply it to the types Int and Char it constructs a type TupleList Int Char, which is synonymous to [(Int, Char)]:

tupleList :: TupleList Int Char
tupleList = [(1, 'a'), (2, 'b')]