4 ms·
I'll try to explain it. The article used F#, but I'll explain using Haskell, and first I'll explain dome Haskell notation, because I learned it while learning H
by trealira 2y ago
I'll try to explain it. The article used F#, but I'll explain using Haskell, and first I'll explain dome Haskell notation, because I learned it while learning Haskell.
In Haskell, you have types. Concrete types have names that start with an uppercase letter, and generic types have lowercase letters.
inc :: Int -> Int
inc x = x + 1
not :: Bool -> Bool
not True = False
not False = True
-- id returns whatever it's given unchanged,
-- no matter the type.
id :: a -> a
id x = x
You also have more complex types:
data IntOrChar = AnInt Int | AChar Char
You can match on the "AnInt" part or the "AChar" part. They're like tags.
-- Increment it if it's an Int, otherwise leave it
f :: IntOrChar -> IntOrChar
f (AnInt n) = AnInt (n + 1)
f (AChar c) = AChar c
The letter "n" is the name of a variable of type Int, and "c" is likewise the name of a variable of type Char.
You can have generic data types in the definition of a data tyñe and still add those tags. Generic type parameters are lowercase, just like in functions.
data Maybe a = Nothing | Just a
You could have functions that define the a type explicitly:
someFn :: Maybe Int -> Maybe Int
Or it could be generic over that type parameter:
someFn :: Maybe a -> Maybe a
"Maybe" is a type constructor rather than a type itself. You can also have other type constructors, e.g. this binary tree definition (which is recursive in this case):
data Tree a = Leaf a | Branch a (Tree a) (Tree a)
In function definitions, you can be generic over type constructors, too. You would write it like this:
someFn :: t a -> t a
That "t" could be a Maybe, or a Tree, or a list, or any type constructor.
In Haskell, Monad is basically an interface where it implements two functions: the infix function ">>=" and the function "return". The interface looks like this:
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
return :: a -> m a
">>=" takes two parameters: some "m a" value, and a function that takes an "a" and returns an "m b", then returns an "m b", where "m" is a type constructor like "Maybe", and "a" and "b" are simple types like Int.
Here's how you could write the Monad instance for Maybe:
instance Monad Maybe where
return :: a -> Maybe a
return x = Just x
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
maybeX >>= f = case maybeX of
Nothing -> Nothing
Just x -> f x
Here's how you could write it for lists:
instance Monad [] where
return :: a -> [a]
return x = [x]
(>>=) :: [a] -> (a -> [b]) -> [b]
xs >>= f = concatMap f xs