content: typeclasses

This commit is contained in:
Maciej Jur 2023-11-08 21:20:15 +01:00
parent 0ba475fd83
commit a00d8f26a6
Signed by: kamov
GPG key ID: 191CBFF5F72ECAFD
4 changed files with 334 additions and 244 deletions

View file

@ -20,7 +20,7 @@ export default defineConfig({
remarkDirective,
// NOTE: pinned ^5.0.0
remarkMath,
[remarkEmoji, {accessible: true}],
[remarkEmoji as any, {accessible: true}],
[remarkRuby, {sep: ';'}],
remarkBib,
],

View file

@ -15,7 +15,7 @@
"@astrojs/solid-js": "^3.0.2",
"@citation-js/plugin-bibtex": "^0.7.2",
"@js-temporal/polyfill": "^0.4.4",
"astro": "^3.4.3",
"astro": "^3.4.4",
"astro-pagefind": "^1.3.0",
"chart.js": "^4.4.0",
"citation-js": "^0.7.4",
@ -39,10 +39,10 @@
"unist-util-visit": "^5.0.0"
},
"devDependencies": {
"@types/leaflet": "^1.9.7",
"@types/leaflet.markercluster": "^1.5.3",
"@types/reveal.js": "^4.4.5",
"@types/unist": "^3.0.1",
"@types/leaflet": "^1.9.8",
"@types/leaflet.markercluster": "^1.5.4",
"@types/reveal.js": "^4.4.6",
"@types/unist": "^3.0.2",
"pagefind": "^1.0.3",
"sass": "^1.69.5",
"sharp": "^0.32.6"

File diff suppressed because it is too large Load diff

View file

@ -13,7 +13,7 @@ I've found them pretty confusing, but in reality they are an incredibly elegant
## Why?
In Haskell, we can write monomorphic functions which accepts concrete types.
In Haskell, we can write monomorphic functions which accept concrete types.
As an example, the function `add` shown below adds together two values of type `Int`.
```haskell
@ -138,10 +138,100 @@ When `Num` is applied to `Int`, it becomes a constraint on the `Int` type, indic
```haskell
Num Int :: Constraint
```
Another example of a kind in Haskell is the kind of unary type constructors `* -> *`.
These unary type constructors are similar to generic types in other languages because they accept a type parameter and produce a new type.
The signature `* -> *` signifies that the type constructor transforms one concrete type into another concrete type.
An example of a trivial type constructor `Item` is shown below.
```haskell
data Item a = MkItem a
Item :: * -> *
Item Int :: *
Item String :: *
```
In this definition, `Item` is a unary type constructor because it takes a type parameter `a` and produces a new type `Item a`, where `a` can be any concrete type.
A commonly used example of a unary type constructor in Haskell is the `Maybe` type.
`Maybe` is used for representing optional values and handling potentially missing or undefined data in a type-safe manner.
Its definition is as follows:
```haskell
data Maybe a = Nothing | Just a
Maybe :: * -> *
```
Haskell type constructors can be parameterized with more than one type variable, as seen in the case of binary type constructors.
An example of a binary type constructor is the `Either` data type:
```haskell
data Either a b = Left a | Right b
Either :: * -> * -> *
Either String :: * -> *
Either String Int :: *
```
In this definition, `Either` is a binary type constructor because it requires two type parameters, `a` and `b`, to create a new type, `Either a b`.
The `Either` type is often used for scenarios where a value can have one of two possible types, such as representing success or failure or providing an alternative to error handling.
Conventionally, the `Left` value indicates error conditions, while the `Right` value signifies valid or correct values.
### Higher Kinded Types
### The venerable monad
In Haskell, understanding the concept of "Higher Kinded Types" is crucial for grasping how certain more abstract type classes work.
HKTs involve type classes that are parameterized by type constructors, rather than just simple types.
The `Functor` type class is an example of a HKT class.
It defines two fundamental operations, `fmap` and `<$`, which operate on a type constructor `f`.
The Functor type class is defined as follows:
```haskell
class Functor f where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
Functor :: (* -> *) -> Constraint
```
The `Functor` type class is not constrained to specific types but is rather parameterized by type constructors.
Its kind signature is `(* -> *) -> Constraint`, indicating that it works with type constructors.
This allows it to be applied to types like `Maybe`, `List`, or other container types that accept a type argument.
Similarly to `Functor`, the `Monad` type class is another example of a HKT type class.
It defines functions for monadic operations, such as `>>=`, `>>`, and `return`.
The definition of the `Monad` type class is as follows:
```haskell
class Monad m where
(>>=) :: m a -> ( a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
Monad :: (* -> *) -> Constraint
```
Like the `Functor` type class, the `Monad` type class is not tied to specific types but is parameterized by type constructors.
Its kind signature is also `(* -> *) -> Constraint`.
It is worth noting that type classes with a kind of `(* -> *) -> Constraint` can be applied to kinds like `* -> * -> *`.
An example of this is the `Functor` instance of `Either`:
```haskell
instance Functor (Either a) where
fmap _ (Left x) = Left x
fmap f (Right x) = Right (f x)
```
In the instance declaration above, we specify that, for any type `a`, `Either a` is an instance of the `Functor` type class.
This allows you to use the `fmap` function with `Either a`, providing a way to map over the second type argument of the `Either` type while keeping the first type argument fixed.
## Other languages