美文网首页
几种 (applicative) functor/monad 的

几种 (applicative) functor/monad 的

作者: wenpin | 来源:发表于2018-12-02 12:25 被阅读0次

    学习 haskell 的过程中,functor/monad 的运算和应用是个坎。

    光是从这几个的类簇(类型类)的定义来看,都太抽象了。 learn you a great haskell 是很好的入门书。对几种常见的 functor(monad) 都有介绍。但是在介绍它们的运算中符号使用得太灵活。同样的 f 有时是 functor, 有时是 function. 为了好好掌握,自己作了一下演算对比总结。

    Laws

    -- functor
    fmap id == id
    
    -- applicative functor
    pure id <*> v = v
    pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
    pure fn <*> pure x = pure (fn x)
    u <*> pure y = pure ($ y) <*> u
    
    -- Monad
    return x >> f = f x
    m >>= return = m
    (m >>= f) >> g = m >>= (\x -> f x >>= g)
    

    Definitions

    class Functor f where
      fmap :: (a -> b) -> f a -> f b
    
    class (Functor fr) => Applicative fr where
      fmap :: (a -> b) -> fr a -> fr b
      pure :: a -> fr a
      (<*>) :: fr (a -> b) -> fr a -> fr b
    
    class Monad m where
      return :: a -> ma
    
      (>>=) :: ma -> (a -> m a) -> mb
    
      (>>) :: m a -> m b -> m b
      m x >> m y = m x >>= \_ -> m y
    
      fail :: String -> m a
      fail msg = error msg
    
    liftA2 :: (Applicative fr) => (a -> b -> c) -> fr a -> fr b -> fr c
    liftA2 fn x y = fn <$> x <*> y = fmap fn x <*> y
    
    sequenceA :: (Applicative fr) => [fr a] -> fr [a]
    sequenceA [] = pure []
    sequenceA (x:xs) = (:) <$> x <*> sequenceA xs
    sequenceA = foldr (liftA2 (:)) (pure [])
    
    (<$>) :: (Functor fr) => (a -> b) -> fr a -> fr b
    fn (<$>) x = fmap fn x
    (<$>) = `fmap`
    
    liftA2 :: (Applicative fr) => (a -> b -> c) -> fr a -> fr b -> fr c
    liftA2 fn x y = fn <$> x <*> y = fmap fn x <*> y
    
    sequenceA :: (Applicative fr) => [fr a] -> fr [a]
    sequenceA [] = pure []
    sequenceA (x:xs) = (:) <$> x <*> sequenceA xs
    sequenceA = foldr (liftA2 (:)) (pure [])
    

    Instances

    Maybe

    instance Applicative Maybe where
      -- functor
      fmap :: (a -> b) -> Maybe a -> Maybe b
      fmap f (Just x) = Just (f x)
      fmap Nothing = Nothing
    
      -- applicative functor
      pure :: a -> Just a
      pure = Just
    
      (<*>) :: Maybe(a -> b) -> Maybe a -> Maybe b
      Nothing <*> _ = Nothing
      (Just f) <*> Nothing = fmap f Nothing = Nothing
      (Just f) <*> (Just x) = fmap f (Just x) = Just (f x)
      (Just f) <*> something = fmap f something
    
      liftA2 :: (a -> b -> c) -> Maybe a -> Maybe b -> Maybe c
      liftA2 fn (Maybe x) (Maybe y)
        = fn <$> (Maybe x) <*> (Maybe y)
        = fmap fn (Maybe x) <*> (Maybe y)
        = Maybe (fn x) <*> Maybe y
        = Maybe (fn x y)
    
      sequenceA :: [Maybe a] -> Maybe [a]
      sequenceA :: (Maybe x):maybes = fmap (:) (Maybe x) <*> sequenceA maybes = Maybe (x:) <*> maybes
      sequenceA = foldr (liftA2 (:)) (Just [])
    
      -- monad
      return x = Just x
    
      (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
      Nothing >>= f = Nothing
      Just x >>= f = f x
    
      foo :: Maybe String
      foo = Just 3 >>= \x -> Just "!" >>= \y -> Just (show x ++ y)
        = Just 3 >>= (\x -> Just "!" >>= (\y -> Just (show x ++ y)))
        = Just "!" >>= (\y -> Just (show 3 ++ y))
        = Just (show 3 ++ "!")
        = "3!"
    
      fail _ = Nothing
    

    (Either e)

    data Either a b = Left a | Right b
    
    -- functor
    instance Functor (Either a) where
      fmap :: (b -> c) -> Either a b -> Either a c
      fmap f (Right x) = Right (f x)
      fmap f (Left x) = Left x
    
    -- monad
     instance (Error e) => Monad (Either e) where
       return :: a -> (Either e) a
       return x = Right x
    
       (>>=) :: (Either e a) -> (a -> Either e a) -> (Either e a)
       Right x >>= f = f x
       Left err >>= f = Left err
       fail msg = Left (strMsg msg)
    

    List

    instance Applicative [] where
      fmap :: (a -> b) -> [a] -> [b]
      fmap = map
      fmap [] = []
      fmap fn (x:xs) = (fn x):(fmap fn xs)
    
      pure :: a -> [a]
      pure x = [x]
    
      (<*>) :: [(a -> b)] -> [a] -> [b]
      fs <*> xs = [f x | f <- fs, x <- xs]
    
      liftA2 :: (a -> b -> c) -> [a] -> [b] -> [c]
      liftA2 fn xs ys
        = fn <$> xs <*> ys
        = fmap fn xs <*> ys
        = map fn xs <*> ys
        = [fn x y | x <- xs, y <- ys]
    
      sequenceA :: [[a]] -> [[a]]
      sequenceA (xs:xss) = map (:) x <*> sequenceA xss
      sequenceA = foldr (liftA2 (:)) ([[]])
    
    instance Monad [] where
      return x = [x]
    
      (>>=) :: [a] -> (a -> [b]) -> [b]
      xs >>= f = concat (map f xs)
    
      foo :: [(Int, String)]
      foo = [1, 2] >>= \n -> ['a', 'b'] >>= \ch -> return (n, ch)
        = [1, 2] >>= (\n -> ['a', 'b'] >>= (\ch -> return (n, ch)))
        = concat [['a', 'b'] >>= (\ch -> return (1, ch)),
          ['a', 'b'] >>= (\ch -> return (2, ch))]
        = concat [concat [[(1, 'a')], [(1, 'b')]],
          concat [[(2, 'a')], [(2, 'b')]]]
        = concat [[(1, 'a'), (1, 'b')], [(2, 'a'), (2, 'b')]]
        = [(1, 'a'), (1, 'b'), (2, 'a'), (2,'b')]
    
      fail _ = []
    
    

    IO

    instance Applicative IO where
      fmap :: (a -> b) -> IO a -> IO b
      fmap f action = do
        result <- action
        return (f action)
    
      pure :: a -> IO a
      pure = return
      pure x = return x
    
      (<*>) :: IO(a -> b) -> IO a -> IO b
      a <*> b = do
        f <- a
        x <- b
        return (f x)
    
      liftA2 :: (a -> b -> c) -> IO a -> IO b -> IO c
      liftA2 fn (IO x) (IO y)
        = fn <$> (IO x) (IO y)
        = fmap fn (IO x) <*> (IO y)
        = IO (fn x) <*> (IO y)
        = IO (fn x y)
    
      sequenceA :: [IO a] -> IO [a]
      sequenceA = foldr (liftA2 (:)) (IO [])
    

    function

    instance Applicative ((->) r) where
      fmap :: (a -> b) -> (r -> a) -> (r -> b)
      fmap f g = (\x -> f(g(x)))
      fmap = (.)
    
      pure :: a -> (r -> a)
      pure x = (\_ -> x)
    
      (<*>) :: (r -> (a -> b)) -> (r -> a) -> (r -> b)
      f <*> g = \x -> f x (g x)
    
    instance Monad ((->) r) where
      return :: r -> (r -> a)
      return x = \_ -> x
    
      (>>=) :: (r -> a) -> (a -> (r -> b)) -> r -> b
      h >>= fn = \w -> fn (h w) w
    

    ZipList

    instance Applicative ZipList where
      fmap :: (a -> b) -> ZipList a -> ZipList b
    
      pure :: a -> ZipList [a]
      pure x = ZipList (repeat x)
    
      (<*>) :: ZipList[a -> b] -> ZipList [a] -> ZipList [b]
      ZipList fs <*> ZipList xs = ZipList (zipWith (\f x -> f x) fs xs)
    
      liftA2 :: (a -> b -> c) -> ZipList a -> ZipList b -> ZipList c
        = fn <$> ZipList xs <*> ZipList ys
        = fmap fn ZipList xs <*> ZipList ys
        = ZipList (map fn xs) <*> ZipList ys
        = ZipList (zipWith (\f x -> f x) (map fn xs) ys)
    
      sequenceA :: [ZipList a] -> ZipList [a]
      sequenceA ((ZipList xs):zls) = ZipList (map (:) xs) <*> sequenceA zls
      sequenceA = foldr (liftA2 (:)) (ZipLits [])
    

    相关文章

      网友评论

          本文标题:几种 (applicative) functor/monad 的

          本文链接:https://www.haomeiwen.com/subject/igrjcqtx.html