-1

Normally when using type declarations we do:

function_name :: Type -> Type

However in an exercise I am trying to solve there is the following structure:

function_name :: Type a -> Type a

or explicitly as in the exercise

alphabet :: DFA a -> Alphabet a
alphabet = undefined

What does a stand for?

Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
timtam
  • 220
  • 2
  • 9
  • 4
    `a` is a type parameter. – Willem Van Onsem Mar 15 '21 at 12:29
  • 1
    It's usually called a "type variable", so googling eg "Haskell type variable" should give some good learning resources. If you know about "generics" in other languages, this use case is very similar to that. – Robin Zigmond Mar 15 '21 at 13:28
  • 2
    Does this answer your question? [Getting started with Haskell](https://stackoverflow.com/questions/1012573/getting-started-with-haskell) – Enlico Mar 15 '21 at 13:48

1 Answers1

1

Short answer: it's a type variable.

At the computation level, the way we define functions is to use variables to refer to their arguments. Like this:

f x = x + 3

Here x is a variable, and its value will be chosen when the function is called. Haskell has a similar (but not identical...) mechanism in its type sublanguage. For example, you can write things like:

type F x = (x, Int, x)
type Endo a = a -> a -> a

Here again x is a variable in the first one (and a in the second), and its value will be chosen at use sites. One can also use this mechanism when defining new types. (The previous two examples just give new names to existing types, but the following does more.) One of the most basic nontrivial examples of this is the Maybe family of types:

data Maybe a = Nothing | Just a

The things on the right of the = are computation-level, so you can mostly ignore them for now, but on the left we are declaring a new family of types Maybe which accepts other types as an argument. For example, Maybe Int, Maybe (Bool, String), Maybe (Endo Char), and even passing in expressions that have variables like Maybe (x, Int, x) are all possible.

Syntactically, type constructors (things which are defined as part of the program text and that we expect the compiler to look up the definition for) start with an upper case letter and type variables (things which will be instantiated later and so don't currently have a concrete definition) start with lower case letters.

So, in the type signature you showed:

alphabet :: DFA a -> Alphabet a

I suspect there are actually two constructs new to you, not just one: first, the type variable a that you asked about, and second, the concept of type application, where we apply at the type level one "function-like" type to another. (Outside of this answer, people say "parameterized" instead of "function-like".)

...and, believe it or not, there is even a type system for types that makes sure you don't write things like these:

Int a -- Int is not parameterized, so shouldn't be applied to arguments
Int Char -- ditto
Maybe -> String -- Maybe is parameterized, so should be applied to
                -- arguments, but isn't
Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380