### A Queer Example

However, just to clarify things and hopefully get a better mental picture of how Haskell really treats types, let’s play with a really weird typeclass, and find a way to make an instance of it.

```
class Weird p where
weird :: j k -> p k j
```

The `weird`

function takes one parameter, and returns a single, concrete type. We look for `->`

to determine parameters and return values. However, the type of the argument and the return value is a little more complicated. Let’s work it out.

Since `(j k)`

must be a concrete type, we can derive the kinds of `j`

and `k`

quite easily, because `k`

itself must be a concrete type, and `j`

is clearly a type constructor, that takes a single concrete type (represented by `k`

).

```
k :: *
j :: * -> *
```

Since we have derived the kinds of `j`

and `k`

, we can figure out `p`

, since `p`

is also clearly a type constructor, taking two types, `k`

and `j`

. And we know the kinds of `k`

and `j`

.

```
p :: * -> (* -> *) -> *
```

What this `Weird`

typeclass is saying, is that instances of it, represented by `p`

, must be of kind: `* -> (* -> *) -> *`

. This is no different from having a typeclass as follows:

```
class Eq a where
(==) :: a -> a -> Bool
```

In this case, `a`

is obviously a concrete type, and has kind of `a :: *`

.

Similarly,

```
class Functor f where
fmap :: (a -> b) -> f a -> f b
```

In this case, `f`

is clearly a type constructor taking one concrete type, and hence `f :: * -> *`

. Hence, instances of the `Functor`

typeclass, as you are probably already familiar with by now, expects a type constructor taking one concrete type. Examples of those are `[]`

and `Maybe`

.

Hence, instances of `Weird`

must be **type constructors**, taking one conrete type, and another type constructor (that takes one concrete type). Hence, the kind is

```
p :: * -> (* -> *) -> *.
```

Let’s construct everything ourselves.

Since `k`

is a concrete type, we can construct one trivially. Note that we don’t really have to do this, we could just as well use any existing such type, such as `Int`

. We can test this using:

```
:t SomeK
data SomeK = SomeK deriving (Show)
```

Since `j`

is a type constructor that expects a concrete type we can also construct `j`

quite easily. Again note that we don’t really have to do this construction, we could just use an existing such type, such as `Maybe`

(I’m using this loosely). We can test this using:

```
:t SomeJ SomeK
data SomeJ a = SomeJ a deriving (Show)
```

And finally, we know that `p`

is a type constructor that expects two parameters: first a concrete type, and then a type constructor that is going to take a single concrete type. We construct that as well. This we probably have to do, because there isn’t an easily available type that looks like this. In order to ensure that `b`

is treated as a type constructor, we “apply” it to `a`

. We also reverse the resulting type (constructing with `SomeP b a`

results in type `SomeP a b`

) because that’s what the weird function expects. We want to match it. We can test this using:

```
:t SomeP (SomeJ SomeK)
data SomeP a b = SomeP (b a) deriving (Show)
```

Now let’s make an instance of `Weird`

. Remember that the weird function takes one argument, of type `(j k)`

. However, in the function itself, we don’t have to specify the type (since it’s already been specified in the class, obviously). We’ll just call that argument `x`

, in Haskell style. Next, we want to create the function’s body such that it returns a `(p k j)`

. We don’t really care what the function body does, because this is a play on types. We just care about the return type.

```
class Weird where
weird :: j k -> p k j
```

The easiest, immediate thing that is going to return a `(p k j)`

is the `SomeP`

that we constructed (again obviously because we were basing the construction on the requirements of `weird`

. Hence, the `SomeP`

value constructor is going to create a type of `SomeP a b`

, where `a`

represents `k`

, and `b`

represents `j`

. In order for the `SomeP`

value constructor to produce `SomeP a b`

(or equivalently `SomeP k j`

), it’s going to take `SomeP b a`

(or equivalently `SomeP j k`

). `(j k)`

is exactly the type of `x`

. Hence, `SomeP x`

will trigger the type constructor of `SomeP (j k)`

, and create a *type* of `SomeP k j`

. That’s exactly `(p k j)`

.

```
instance Weird SomeP where
weird x = SomeP x
```

We have an instance of `Weird`

! Not saying it’s useful, but well, it’s just to help understanding.