Advertisement
Condiamond

Lectures 8-13

Dec 17th, 2020 (edited)
2,035
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haskell 16.91 KB | None | 0 0
  1. -------------------------------------
  2. -- Lecture 08: Speeding up Haskell --
  3. -------------------------------------
  4.  
  5. -- Difference list
  6.  
  7. newtype DifferenceList a = DL { unDL :: [a] -> [a] }
  8.  
  9. fromList :: [a] -> DifferenceList a
  10. fromList = DL . (++)
  11.  
  12. toList :: DifferenceList a -> [a]
  13. toList (DL f) = f []
  14.  
  15. instance Monoid (DifferenceList a) where
  16.     DL f <> DL g = DL $ f . g
  17.    
  18. -- Strict evaluation (feat. irrefutable patterns)
  19.  
  20. seq :: a -> b -> b
  21. seq _|_ b = _|_
  22. seq _   b = b
  23.  
  24. data    DataWrapper    a = DW a
  25. newtype NewtypeWrapper a = NW a
  26.  
  27. ghci> DW undefined `seq` 22
  28. 22
  29. ghci> NW undefined `seq` 22
  30. *** Exception: Prelude.undefined
  31.  
  32. foldlStrict :: (a -> b -> a) -> a -> [b] -> a
  33. foldlStrict f a []     = a
  34. foldlStrict f a (x:xs) = let aa = f a x
  35.                          in seq aa (foldlStrict f aa xs)
  36.                    
  37. class NFData a where  -- Normal Form Data
  38.     rnf :: a -> ()
  39.     rnf a = a `seq` ()
  40.    
  41. deepseq :: NFData a => a -> b -> b
  42. a `deepseq` b = rnf a `seq` b
  43.  
  44. f !a  = ... ≡ f a | a `seq` False = undefined; f a = ... -- to transform the argument into its weak head normal form
  45.  
  46. ($!) :: (a -> b) -> a -> b                 -- strict function application
  47. f $! x = let !vx = x in f vx
  48.  
  49. ($!!) :: NFData a => (a -> b) -> a -> b  -- deep strict function application
  50. f $!! x = x `deepseq` f x
  51.  
  52. f :: (a, b) -> Int
  53. f (a, b) = const 1 a   -- pair pattern is too strict
  54.  
  55. g :: (a, b) -> Int
  56. g ~(a, b) = const 1 a  -- irrefutable pattern ≡ lazy pattern
  57.  
  58. f1 :: Either e Int -> Int
  59. f1 ~(Right 1) = 42
  60.  
  61. ghci > f (Left "kek")
  62. 42
  63. ghci > f (error "mda")
  64. 42
  65.  
  66. -- Stream fusion
  67.  
  68. data Step s a = Done
  69.               | Skip    s
  70.               | Yield a s
  71.  
  72. data Stream a = forall s . Stream (s -> Step s a) s
  73.  
  74. stream :: forall a . [a] -> Stream a
  75. stream xs = Stream next xs
  76.   where
  77.     next :: [a] -> Step [a] a
  78.     next []     = Done
  79.     next (x:xs) = Yield x xs
  80.    
  81. unstream :: forall a . Stream a -> [a]
  82. unstream (Stream next s0) = go s0
  83.   where
  84.     go s = case next s of
  85.              Done       -> []
  86.              Skip ss    -> go ss
  87.              Yield a ss -> a : go ss
  88.              
  89. mapS :: forall a b . (a -> b) -> Stream a -> Stream b
  90. mapS f (Stream next s) = Stream nextt s
  91.   where
  92.     nextt xs = case next xs of
  93.                     Done       -> Done
  94.                     Skip ss    -> Skip ss
  95.                     Yield a ss -> Yield (f a) ss
  96.  
  97. filterS :: forall a . (a -> Bool) -> Stream a -> Stream a
  98. filterS p (Stream next s) = Stream nextt s
  99.   where
  100.     nextt xs = case next xs of
  101.                     Done       -> Done
  102.                     Skip ss    -> Skip ss
  103.                     Yield a ss -> if p a then Yield a ss else Skip ss
  104.                    
  105. -- Mutable objects innit
  106.  
  107. data ST s a  -- The strict state-transformer monad
  108.  
  109. runState :: State s a -> s -> (a, s)  -- use evalState with state to get result
  110. runST    :: (forall s. ST s a) -> a   -- forall trick
  111.  
  112. data STRef s a  -- a mutable variable
  113.  
  114. newSTRef    :: a -> ST s (STRef s a)
  115. readSTRef   :: STRef s a -> ST s a
  116. writeSTRef  :: STRef s a -> a -> ST s ()
  117. modifySTRef :: STRef s a -> (a -> a) -> ST s ()
  118.  
  119. class Monad m => MArray a e m where  -- type class for all arrays
  120.  
  121. data STArray s i e :: * -> * -> * -> *  -- Mutable, boxed, non-strict arrays
  122. -- s: the state variable argument for the ST type
  123. -- i: the index type of the array (should be an instance of Ix), usually Int
  124. -- e: the element type of the array.
  125.  
  126. data STUArray s i e  -- A mutable array with unboxed elements
  127.                      -- (Int, Double, Bool, etc.)
  128.                      
  129. newArray   :: Ix i => (i, i) -> e -> m (a i e)
  130. readArray  :: (MArray a e m, Ix i) => a i e -> i -> m e
  131. writeArray :: (MArray a e m, Ix i) => a i e -> i -> e -> m ()
  132.  
  133. data Vector    a  -- immutable vectors
  134. data MVector s a  -- mutable vectors
  135.  
  136. -- immutable vectors
  137. (!) :: Vector a -> Int -> a  -- O(1) indexing
  138. fromList :: [a] -> Vector a
  139. -- map, filter, etc.
  140.  
  141. -- mutable vectors
  142. read   :: (PrimMonad m, MVector v a) => v (PrimState m) a -> Int -> m a
  143. write  :: (PrimMonad m, MVector v a) => v (PrimState m) a -> Int -> a -> m ()
  144. grow   :: PrimMonad m => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
  145. freeze :: PrimMonad m => MVector (PrimState m) a -> m (Vector a)
  146.  
  147. ---------------------------------------------------------
  148. -- Lecture 09: Concurrency, Exceptions and parallelism --
  149. ---------------------------------------------------------
  150.  
  151. -- forking a thread
  152.  
  153. forkIO :: IO () -> IO ThreadId  -- creates lightweight thread
  154.  
  155. import Control.Concurrent
  156.  
  157. main = do
  158.   _threadId <- forkIO $ do
  159.     threadDelay 1000000
  160.     putStrLn "Forked thread awake"
  161.   threadDelay 2000000
  162.   putStrLn "Main thread finishes"
  163.  
  164. -- Mutex variable
  165.  
  166. data MVar a  -- empty or full box; mutex variable
  167.  
  168. newEmptyMVar :: IO (MVar a)           -- create empty box
  169. putMVar      :: MVar a -> a -> IO ()  -- fill box with value
  170. takeMVar     :: MVar a -> IO a        -- take var with block
  171.  
  172. import Control.Concurrent
  173.  
  174. main = do
  175.   tm1 <- newEmptyMVar
  176.   tm2 <- newEmptyMVar
  177.   _threadId1 <- forkIO $ do
  178.     threadDelay 1000000
  179.     putMVar tm1 100500
  180.   _threadId2 <- forkIO $ do
  181.     threadDelay 1000000
  182.     putMVar tm2 "This is horosho"
  183.  
  184.   r1 <- takeMVar tm1
  185.   r2 <- takeMVar tm2
  186.  
  187. -- K i l l i n g t h r e a d s (figuratively speaking) and catching Exceptions
  188.  
  189. throwTo :: Exception e => ThreadId -> e -> IO ()
  190.  
  191. killThread :: ThreadId -> IO ()
  192. killThread tid = throwTo tid ThreadKilled
  193.  
  194. throwIO :: Exception e => e -> IO a
  195. throw :: Exception e => e -> a
  196.  
  197. catch :: Exception e => IO a -> (e -> IO a) -> IO a
  198.  
  199. handle :: Exception e => (e -> IO a) -> IO a -> IO a
  200. handle = flip catch
  201.  
  202. mask_ :: IO a -> IO a -- Executes an IO computation with asynchronous exceptions masked. I.e. any thread which attempts to raise an exception in the current thread with throwTo will be blocked until asynchronous exceptions are unmasked again.
  203.  
  204. -- bracket reminder + finally
  205.  
  206. bracket :: IO a        -- computation to run first, acquiring the resource
  207.         -> (a -> IO b) -- computation to run last, releasing the resource
  208.         -> (a -> IO c) -- main computation to run in-between
  209.         -> IO C
  210.        
  211. finally :: IO a -- computation to run first
  212.         -> IO b -- computation to run afterward
  213.         -> IO a
  214.        
  215. -- Control.Concurrent.Async
  216.  
  217. withAsync       :: IO a -> (Async a -> IO b) -> IO b
  218. wait            :: Async a -> IO a
  219. cancel          :: Async a -> IO ()
  220. concurrently    :: IO a -> IO b -> IO (a, b)
  221. race            :: IO a -> IO b -> IO (Either a b)
  222. mapConcurrently :: Traversable t => (a -> IO b) -> t a -> IO (t b)
  223.  
  224. -- Software Transactional Memory
  225.  
  226. data STM a  -- software transactional memory
  227. instance Monad STM
  228.  
  229. atomically :: STM a -> IO a
  230.  
  231. data TVar a -- transactional variable
  232. newTVar   :: a -> STM (TVar a)
  233. readTVar  :: TVar a -> STM a
  234. writeTVar :: TVar a -> a -> STM ()
  235.  
  236. retry     :: STM a                   -- try again current transaction
  237. orElse    :: STM a -> STM a -> STM a -- if first retries then call second
  238.  
  239. throwSTM  :: Exception e => e -> STM a
  240. catchSTM  :: Exception e => STM a -> (e -> STM a) -> STM a
  241.  
  242. -- \/ example \/
  243.  
  244. type Account = TVar Integer
  245.  
  246. credit :: Integer -> Account -> STM ()
  247. credit amount account = do
  248.     current <- readTVar account
  249.     writeTVar account (current + amount)
  250.  
  251. debit :: Integer -> Account -> STM ()
  252. debit amount account = do
  253.     current <- readTVar account
  254.     writeTVar account (current - amount)
  255.  
  256. transfer :: Integer -> Account -> Account -> STM ()
  257. transfer amount from to = do
  258.     debit amount from
  259.     credit amount to
  260.    
  261. -- Eval
  262.  
  263. data Eval a -- Eval is monad for parallel computation
  264. instance Monad Eval
  265.  
  266. runEval :: Eval a -> a  -- pull the result out of the monad
  267.  
  268. rpar :: a -> Eval a  -- suggest to parallel, create *spark*
  269. rseq :: a -> Eval a  -- wait for evaluation of argument (eval it to WHNF)
  270.  
  271. -------------------------------------------------
  272. -- Lecture 10: Lens... but no Template Haskell --
  273. -------------------------------------------------
  274.  
  275. -- Lens
  276.  
  277. type Lens  s t a b = forall f. Functor f => (a -> f b) -> (s -> f t)
  278. type Lens' s   a   = Lens s s a a
  279.  
  280. lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b
  281. lens get set = \f s -> set s <$> f (get s)
  282.  
  283. newtype Const a x = Const { getConst :: a }
  284. instance Functor (Const a) where
  285.    fmap _ (Const v) = Const v
  286.  
  287. view :: Lens' s a -> s -> a
  288. view l s = getConst $ l Const s
  289.  
  290. newtype Identity a = Identity { runIdentity :: a }
  291. instance Functor Identity where
  292.     fmap f (Identity x) = Identity (f x)
  293.    
  294. over :: Lens' s a -> (a -> a) -> s -> s
  295. over l fn s = runIdentity $ l (Identity . fn) s
  296.  
  297. set :: Lens' s a -> a -> s -> s
  298. set l a s = runIdentity $ l (Identity . const a) s
  299.  
  300. -- Lens laws
  301.  
  302. 1. view l (set l field obj)      ≡ field
  303. 2. set l (view l obj) obj        ≡ obj
  304. 3. set l field (set l field obj) ≡ set l field obj
  305.  
  306. -- operators
  307.  
  308. (.~) :: Lens' s a -> a        -> (s -> s)
  309. (.=) :: Lens' s a -> a        -> State s ()
  310.  
  311. (%~) :: Lens' s a -> (a -> a) -> (s -> s)
  312. (%=) :: Lens' s a -> (a -> a) -> State s ()
  313.  
  314. (^.) :: s -> Lens' s a -> a
  315.  
  316. -- Traversal
  317.  
  318. type Traversal  s t a b = forall f . Applicative f => (a -> f b) -> (s -> f t)
  319. type Traversal' s   a   = forall f . Applicative f => (a -> f a) -> (s -> f s)
  320.  
  321. -- Getting
  322.  
  323. type Getting r s a = (a -> Const r a) -> s -> Const r s
  324.  
  325. toListOf :: Getting (Endo [a]) s a -> s -> [a]
  326. (^..)    :: s -> Getting (Endo [a]) s a -> [a]
  327.  
  328. -- Prism
  329.  
  330. type Prism s t a b = forall p f. (Choice p, Applicative f) => p a (f b) -> p s (f t)
  331.    
  332. preview :: Prism' s a -> s -> Maybe a
  333. review :: Prism' s a -> a -> s
  334. _Left :: Prism' (Either a b) a
  335. _Just :: Prism' (Maybe a) a
  336. _Cons :: Prism' [a] (a, [a])
  337. _Nil :: Prism' [a] ()
  338.  
  339. -- \/ Prism examples \/
  340.  
  341. ghci> preview _Left (Left "hi")
  342. Just "hi"
  343. ghci> preview _Left (Right "hi")
  344. Nothing
  345.  
  346. ghci> review _Left "hi"
  347. Left "hi"
  348.  
  349. ghci> preview _Cons []
  350. Nothing
  351.  
  352. ghci> preview _Cons [1,2,3]
  353. Just (1, [2,3])
  354.  
  355. ghci> preview _Nil []
  356. Just ()
  357.  
  358. ghci> preview _Nil [1,2,3]
  359. Nothing
  360.  
  361. -------------------------------------
  362. -- Lecture 11: Brand new DSL world --
  363. -------------------------------------
  364.  
  365. -- GADT example
  366.  
  367. data ArithExpr a where
  368.   AENum  :: Int -> ArithExpr Int
  369.   AEPlus :: ArithExpr Int -> ArithExpr Int -> ArithExpr Int
  370.   AEAnd  :: ArithExpr Bool -> ArithExpr Bool -> ArithExpr Bool
  371.   AEGt   :: ArithExpr Int -> ArithExpr Int -> ArithExpr Bool
  372.  
  373. -- Existential types, type equality & type application
  374.  
  375. data SomeAE where
  376.   SomeAE :: (Typeable a, Show a) => ArithExpr a -> SomeAE
  377.  
  378. -- | The class 'Typeable' allows
  379. -- a concrete representation of
  380. -- a type to be calculated.
  381. class Typeable (a :: k)
  382.  
  383. -- | Propositional equality.
  384. -- If @a :~: b@ is inhabited by some
  385. -- terminating value, then the type @a@
  386. -- is the same as the type @b@.
  387. data a :~: b where
  388.   Refl :: a :~: a
  389.  
  390. -- | Extract a witness of equality
  391. -- of two types
  392. eqT
  393.   :: forall a b. (Typeable a, Typeable b)
  394.   => Maybe (a :~: b)
  395.  
  396. {-# LANGUAGE TypeApplications #-}
  397. {-# LANGUAGE ScopedTypeVariables #-}
  398.  
  399. parseInt
  400.   :: String -> Maybe (ArithExpr Int)
  401. parseInt s = parse s >>=
  402.   \(SomeAE (expr :: ArithExpr t)) ->
  403.     do
  404.       Refl <- eqT @t @Int
  405.       pure expr
  406.  
  407. -- Universal quantifier & rank-N types
  408.  
  409. length :: forall a . [a] -> Int
  410.  
  411. {-# LANGUAGE RankNTypes #-}
  412.  
  413. applyToTuple :: (forall a. [a] -> Int) -> ([b], [c]) -> (Int, Int)
  414. applyToTuple f (x, y) = (f x, f y)
  415.  
  416. Rank 0: Int
  417. Rank 1: forall a . a -> Int
  418. Rank 2: (forall a . a -> Int) -> Int
  419. Rank 3: ((forall a . a -> Int) -> Int) -> Int
  420.  
  421. -- ST, once again, ffs
  422.  
  423. runST :: forall α. (forall s. ST s α) -> α
  424.  
  425. newSTRef :: forall α s. α -> ST s (STRef s α)
  426. readSTRef :: forall α s. STRef s α -> ST s α
  427. writeSTRef :: forall α s. STRef s α -> α -> ST s ()
  428.  
  429. -- Scoped type variables
  430.  
  431. {-# LANGUAGE ScopedTypeVariables #-}
  432.  
  433. calc3 :: forall a. Num a => a -> a -> a
  434. calc3 a b = a + f b
  435.   where
  436.     f :: a -> a
  437.     f = (+ 10)
  438.    
  439. -- TAGLESS FINAL
  440.  
  441. class ArithExpr expr where
  442.   aeNum  :: Int -> expr Int
  443.   aePlus :: expr Int -> expr Int -> expr Int
  444.   aeAnd  :: expr Bool -> expr Bool -> expr Bool
  445.   aeGt   :: expr Int -> expr Int -> expr Bool
  446.  
  447. newtype Interpret a =
  448.   Interpret { interpret :: a }
  449.  
  450. instance ArithExpr Interpret where
  451.   aeNum = Interpret
  452.   aePlus a b = Interpret $
  453.     interpret a + interpret b
  454.   aeAnd a b = Interpret $
  455.     interpret a && interpret b
  456.   aeGt a b = Interpret $
  457.     interpret a > interpret b
  458.  
  459. -------------------------------------
  460. -- Lecture 12: Some fun with kinds --
  461. -------------------------------------
  462.  
  463. -- ConstraintKinds
  464.  
  465. {-# LANGUAGE ConstraintKinds #-}
  466.  
  467. type MyConstraints a = (Read a, Num a, Show a)
  468.  
  469. foo :: MyConstraints a => String -> a -> a
  470.  
  471. -- Datatype promotion
  472.  
  473. {-# LANGUAGE DataKinds #-}
  474.  
  475. data Nat = Z | S Nat
  476.  
  477. data Vec :: * -> Nat -> * where
  478.     Nil  :: Vec a Z
  479.     Cons :: a -> Vec a n -> Vec a (S n)
  480.    
  481. zipV :: Vec a n -> Vec b n -> Vec (a, b) n
  482. zipV       Nil       Nil = Nil
  483. zipV (x :> xs) (y :> ys) = (x, y) :> zipV xs ys
  484.  
  485. -- Heterogenous lists
  486.  
  487. data HList :: [*] -> * where
  488.     HNil :: HList '[]
  489.    (:^) :: a -> HList t -> HList (a ': t)
  490.  
  491. infixr 2 :^
  492.  
  493. -- Instantiating such data types
  494.  
  495. instance Show (HList '[]) where
  496.    show _ = "H[]"
  497.    
  498. instance (Show e, Show (HList l)) => Show (HList (e ': l)) where
  499.     show (x :^ l) = let 'H':'[':s = show l
  500.                     in "H[" ++ show x ++ (if s == "]" then s else ", " ++ s)
  501.                    
  502. -- Type families
  503.  
  504. type family Foo bar :: * where
  505.   Foo Char = Double
  506.   Foo b = b
  507.  
  508. type family Foo bar :: *
  509. type instance Foo Char = Double
  510. type instance Foo Int = Int
  511.  
  512. -- Free monad
  513.  
  514. data Free f a = Pure a | Free (f (Free f a)) -- Free monad is an abstraction of multistep computation where each subsequent step requires some input from the outer context to continue.
  515.  
  516. instance Functor f => Monad (Free f) where
  517.   return = Pure
  518.  
  519.   Pure a >>= f = f a
  520.   Free m >>= f = Free ((>>= f) <$> m)
  521.  
  522. --------------------------
  523. -- Lecture 13: Comonads --
  524. --------------------------
  525.  
  526. -- Comonad
  527.  
  528. class Functor w => Comonad w where
  529.     extract   :: w a -> a
  530.     duplicate :: w a -> w (w a)           -- extend id x
  531.     extend    :: (w a -> b) -> w a -> w b -- fmap f <$> duplicate x
  532.  
  533. -- 'extend' in operator form with arguments flipped
  534. (=>>) :: Comonad w => w a -> (w a -> b) -> w b
  535.  
  536. -- Zippers
  537.  
  538. Zipper(f, a) = a * f'(a)
  539.  
  540. List(a) = 1 + a * List(a) = 1 / (1 - a)
  541. List'(a) = (1 / (1 - a)) ^ 2 = List(a) * List(a)
  542. Zipper(List, a) = List(a) * a * List(a)
  543.  
  544. data ListZipper a = LZ [a] a [a] deriving Functor  -- allows to focus on a single element
  545.  
  546. instance Comonad ListZipper where
  547.     extract :: ListZipper a -> a
  548.     extract (LZ _ x _) = x
  549.    
  550.     extend :: (ListZipper a -> b) -> ListZipper a -> ListZipper b
  551.     extend f lz@(LZ l a s) = LZ (goListL f lz) (f lz) (goListR f lz)
  552.       where
  553.         goListL :: (ListZipper a -> b) -> ListZipper a -> [b]
  554.         goListL f lz@(LZ [] _ _) = []
  555.         goListL f lz@(LZ (x : xs) a s) = f (moveLL lz) : goListL f (moveLL lz)
  556.  
  557.         goListR :: (ListZipper a -> b) -> ListZipper a -> [b]
  558.         goListR f lz@(LZ _ _ []) = []
  559.         goListR f lz@(LZ l a (x : xs)) = f (moveLR lz) : goListR f (moveLR lz)
  560.  
  561. data Tree a = Nil | Node (Tree a) a (Tree a) deriving Functor
  562.  
  563. Tree(a) = 1 + a * Tree^2(a)
  564. Tree'(a) = Tree^2(a) + 2 * a * Tree(a) * Tree'(a) = Tree^2(a) / (1 - 2 * a * Tree(a)) = Tree^2(a) * List(2 * a * Tree(a))
  565. Zipper(Tree, a) = Tree(a) * a * Tree(a) * List(a * Tree(a) + a * Tree(a))
  566.  
  567. data Branch a = LB (BinTree a) a | RB a (BinTree a) deriving Functor
  568. data BinTreeZipper a = BTZ (BinTree a) a (BinTree a) [Branch a] deriving Functor
  569.  
  570. -- Env, Coreader
  571.  
  572. data Env e a = Env e a
  573.  
  574. instance Comonad (Env e) where
  575.     extract :: Env e a -> a
  576.     extract (Env _ a) = a
  577.  
  578.     extend :: (Env e a -> b) -> Env e a -> Env e b
  579.     extend f env@(Env e _) = Env e (f env)
  580.    
  581. -- Traced, Cowriter
  582.  
  583. newtype Traced m a = Traced { runTraced :: m -> a }
  584.  
  585. instance Monoid m => Comonad (Traced m) where
  586.     extract :: Traced m a -> a
  587.     extract  (Traced ma) = ma mempty
  588.  
  589.     extend :: (Traced m a -> b) -> Traced m a -> Traced m b
  590.     extend f (Traced ma) = Traced $ \m -> f (Traced $ \m' -> ma (m <> m'))
  591.    
  592. -- Store, Costate
  593.  
  594. data Store s a = Store (s -> a) s deriving Functor
  595.  
  596. instance Comonad (Store s) where
  597.     extract :: Store s a -> a
  598.     extract  (Store f s) = f s
  599.  
  600.     extend :: (Store s a -> b) -> Store s a -> Store s b
  601.     extend f (Store g s) = Store (f . Store g) s
  602.  
  603. -- codo-notation... one of the many...
  604.  
  605. next123 :: Iterator a -> [a]
  606. next123 = method
  607.         this & next
  608.     i1> this & next
  609.     i2> this & next
  610.     i3> [i1  & extract, i2 & extract, i3 & extract]
  611.    
  612. next123 =
  613.       \_i0 ->
  614.     let i1 =      extend (\this -> this & next) _i0
  615.         i2 =      extend (\this -> this & next)  i1
  616.         i3 =      extend (\this -> this & next)  i2
  617.      in extract $ extend (\this ->
  618.             [i1 & extract, i2 & extract, i3 & extract]) i3
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement