Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent of creating objects in Haskell

I am trying to understand how the following are used:

data Maybe a = Nothing | Just a
data Either a b = Left a | Right b

From my understanding these are parameterized algebraic data types. Coming from an OO background, I would now like to create an instance of these objects. If I do something like:

x = Maybe 10

Is that now a subclass/sub-algebraic-data-type, or wondering what that object is called. I would assume it is a type of some sort. If so, then I am wondering how to create an instance of x. In OO land I would do:

myinstance = new x

This is where coming to Haskell gets me lost and I'm not sure where to search. A few questions to summarize:

  1. What kind of object x is above. If Maybe is a parameterized data type, then x is ~something~ type, not sure.
  2. How to create an instance of x.
  3. What is the instance of x for Maybe, since we passed it 10. Wondering, if the instance value is 10 and has type Int.
like image 991
Lance Avatar asked May 22 '18 07:05

Lance


3 Answers

There is no such thing as Maybe 10 in Haskell. There is Maybe Int, which is a type.

We create a value of a certain type, directly, as

x :: Maybe Int
x = Just 10

or

y :: Maybe Int
y = Nothing

Simple and direct.


edit: Maybe is a type constructor. Just and Nothing are data constructors. By writing Maybe Int we "create" a type. There can't be a definition z :: Maybe ; z = ......

This is known as "kind": the kind of Maybe is * -> *, while e.g. Int's is * and so is Maybe Int's. Try :k at GHCi prompt to see this:

~> :k Int
Int :: *

~> :k Maybe
Maybe :: * -> *

~> :k Maybe Int
Maybe Int :: *

Of course we don't actually create a new type when we write "Maybe Int, it's just that Maybe by itself is not a type of things yet (types of "things" have kind *).

The definition for Maybe is what creates the types Maybe a, for any a we might use. This is known as parametric polymorphism.

So in Haskell, we don't have objects (in the OOP sense). We have values and types.

like image 119
Will Ness Avatar answered Nov 05 '22 14:11

Will Ness


What kind of object x is above. If Maybe is a parameterized data type, then x is ~something~ type, not sure.

You can not construct a Maybe 10, you can for example construct a Just 10. In case 10 is here an Int (well technically it can be any numerical type, but let us ignore that for now), then you constructed a Maybe Int.

Note that a in Maybe a, is one meta level higher: it works with types. Hence a is a type parameter. It thus does not take as value 10, but for example Int.

What you can do however is define a type alias for Maybe Int, for example:

type X = Maybe Int

Note that we here use type as a type alias, not data to construct a data type.

Types (and type aliasses) always start with an upper case, so we can not define a type x, only a type X. A type has no default constructor (which is typically the case in OO programming languages).

How to create an instance of x.

Haskell can derive the most generic type of an expression itself. We thus write an expression that has the type of Maybe Int, so for example

Just 10

In case the type would be too generic (here it will be Num a => Maybe a), we can give a hint to Haskell by using two consecutive colons (::), for eample:

Just 10 :: Maybe Int

or since we already introduced the type alias X:

Just 10 :: X

What is the instance of x for Maybe, since we passed it 10. Wondering, if the instance value is 10 and has type Int.

Welll as said before, types in Haskell have no default constructor. We here have two candidates: Just n with n an Int (in case we use type X), or Nothing. So we pick one of the two:

Just 10 :: X
Nothing :: X

Since you can not change the state of an object anymore after you constructed it (i.e. all objects in Haskell are immutable), that means that it would be strange that a default constructor sets some initial data, and then later methods would change that object.

You can therefore see a data constructor (here Just and Nothing) as a labelled container that holds a group of parameters together in a container, and labels it with what constructor was used. So a graphical view of the objects would be:

+------+   +---------+
| Just |   | Nothing |
+------+   +---------+
|   o  |
+---|--+
    |
    v
 +----+
 | 10 |
 +----+
like image 2
Willem Van Onsem Avatar answered Nov 05 '22 14:11

Willem Van Onsem


When you write an algebraic type definition as

data Maybe a = Nothing | Just a

the LHS is a type construction expression (it states that Maybe has kind * -> *), and the RHS is a disjunction of alternatives each one being a value constructor, so for type Maybe a, Just is an unary constructor that creates an object of this type, and Nothing is the nullary one.

like image 2
bipll Avatar answered Nov 05 '22 13:11

bipll