Add the rest of university notes
This commit is contained in:
366 files changed
+9844
-110
No files matched your search
@@ -0,0 +1,101 @@
|
||||
# Functor
|
||||
|
||||
Parsing an expression in parenthesis:
|
||||
|
||||
```haskell
|
||||
parseP :: Parser AST
|
||||
parseP = do symbol '('
|
||||
t <- exp
|
||||
symbol ')'
|
||||
return t
|
||||
```
|
||||
|
||||
Before we write this sort of code, we need to understand `type classes` (especially `monads`)
|
||||
|
||||
## Types vs Typeclasses
|
||||
|
||||
| Types | Type classes |
|
||||
| ------ | ------------ |
|
||||
| Bool | Eq |
|
||||
| Char | Show |
|
||||
| AST | Num |
|
||||
| String | Functor |
|
||||
| | Monad |
|
||||
|
||||
**Eq**: typeclass equality; A type can only be typeclass equality if two like types can be compared
|
||||
|
||||
A type can be a *member* (instance) of a type class, meaning that if has the properties/functions that the class requires
|
||||
|
||||
e.g. `Bool` is an instance of `Eq` and `Show`
|
||||
|
||||
###### Is there a type that is **not** in `Eq`?
|
||||
|
||||
```haskell
|
||||
(\c -> c :: Int) == (\c -> c :: Int)
|
||||
```
|
||||
|
||||
**ERROR**: No instance for `Eq(Int -> Int)`
|
||||
|
||||
Why?
|
||||
|
||||
```haskell
|
||||
f :: Int -> Int
|
||||
g :: Int -> Int
|
||||
```
|
||||
|
||||
Then `f == g` should be `fn == gn` for every n, the computer cannot do this (halting problem).
|
||||
|
||||
## Type Constructors
|
||||
|
||||
A type constructor takes a type to construct a new type.
|
||||
|
||||
`Maybe` - not a type but a type constructor
|
||||
|
||||
`Maybe String` - a type
|
||||
|
||||
```haskell
|
||||
newtype Parser a = P (String -> [a, String])
|
||||
```
|
||||
|
||||
**Parser** is a type constructor
|
||||
|
||||
**Parser AST** is a type
|
||||
|
||||
Functor is a typeclass of which `parser` is an instance
|
||||
|
||||
##### Functor
|
||||
|
||||
```haskell
|
||||
class Functor f where
|
||||
fmap :: (a -> b) -> fa -> fb
|
||||
|
||||
instance Functor Maybe where
|
||||
fmap g (Just x) = Just (g x)
|
||||
fmap g Nothing = Nothing -- fmap id = id
|
||||
|
||||
-- lists
|
||||
instance Functor [] where
|
||||
fmap g [] = []
|
||||
fmap g (t:ts) = (g t) : fmap g ts
|
||||
|
||||
-- goal: write parser as a functor
|
||||
newtype Parser a = P ( String -> [a, String] )
|
||||
-- Need: fmap :: (a->b) -> Parser a -> Parser b
|
||||
|
||||
instance Functor Parser where
|
||||
fmap g pa = -- parser pa
|
||||
P (\str -> map (\(x,s) -> (gx,s))
|
||||
parse pa str)
|
||||
```
|
||||
|
||||
##### Rules of Functors
|
||||
|
||||
```haskell
|
||||
fmap id = id -- identity
|
||||
fmap (f . g) = fmap f . fmap g
|
||||
```
|
||||
|
||||
Haskell doesn't enforce these rules however it is convention.
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user