Add the rest of university notes
This commit is contained in:
366 files changed
+9844
-110
No files matched your search
@@ -0,0 +1,88 @@
|
||||
# Monad Revision
|
||||
|
||||
You can think of a monad as a container for a data type
|
||||
|
||||
If $M$ is a monad, that means an element of $M$: $M_a$ is some sort of container where $a$ is any datatype
|
||||
|
||||
One of the purposes of the `do` notation is to operate on the whole data structure by specify operations that must apply to each of the elements in the data structure, without having to specify the whole structure.
|
||||
|
||||
$$
|
||||
M_a=\{x_1, x_2, x_3,...\}
|
||||
$$
|
||||
|
||||
```haskell
|
||||
do x <- m
|
||||
let y = x ** 2 + 7
|
||||
return y
|
||||
```
|
||||
|
||||
This extracts an element of type $a$ from $m$, squares and adds 7, and returns the new values as the data structure. Now $M$ is
|
||||
|
||||
$$
|
||||
M_b=\{y_1, y_2, y_3, \ldots\}\\or\\M=\{x_1^2+7, x_2^2+7, x_3^2+7, \ldots\}
|
||||
$$
|
||||
|
||||
The above can be written as a functor
|
||||
|
||||
```haskell
|
||||
fmap (\x -> x**2+7) m
|
||||
```
|
||||
|
||||
Monads have more functionality than functors though
|
||||
|
||||
If $x$ is an element of $a$ or $x :: a$
|
||||
|
||||
```haskell
|
||||
x :: a
|
||||
return x
|
||||
-- we can also write
|
||||
pure x
|
||||
```
|
||||
|
||||
Monads can have containers within containers
|
||||
|
||||
Assume we have function `makeBlob` that maps every element of $a$ to an element of $M_b$
|
||||
|
||||
```haskell
|
||||
makeBlob :: a -> Mb
|
||||
makeBlob x1 = do x <- m
|
||||
y <- makeBlob x
|
||||
return y
|
||||
-- this can be done instead with the bind operator
|
||||
m >>= makeBlob
|
||||
(>>=) :: Ma -> (a -> Mb) -> Mb
|
||||
```
|
||||
|
||||
## The IO Monad
|
||||
|
||||
```haskell
|
||||
square :: Int -> Int
|
||||
square x = x*x
|
||||
|
||||
getInt :: IO Int
|
||||
getInt = do putStrLn "Enter a number: "
|
||||
s <- getLine -- getLine :: IO String
|
||||
return (read s :: Int) --read :: String -> Int
|
||||
|
||||
squareIO :: IO Int
|
||||
squareIO = do x <- getInt
|
||||
let y <- square x
|
||||
return y
|
||||
-- as squareIO :: IO Int, returning y prints it out
|
||||
|
||||
squareIO :: IO () -- unit type, with only one element, also called ()
|
||||
squareIO = do x <- getInt
|
||||
let y <- square x
|
||||
putStrLn("The square " ++ (show x) ++ " is " (show y))
|
||||
return () --return unit type
|
||||
-- in this case we dont even need return () as
|
||||
-- putStrLn :: IO ()
|
||||
|
||||
--recursively asks for list unless 0 entered
|
||||
getList :: IO [Int]
|
||||
getList = do x <- getInt
|
||||
if x == 0 then return []
|
||||
else do
|
||||
xs <- getList
|
||||
return (x:xs)
|
||||
```
|
||||
Reference in new issue
Block a user