第25章:單子變換的升格操作

夢飛發表於2017-03-16
  • 單子變換就是一類函式,用來把單子m包裹成單子t m,同時宣告在這種情況下對應的單子例項。
  • 實際當中,我們常遇到多個單子變換疊加的情況,分析單子變換的型別時,按順序來看
  • 我們把通過疊加單子變換得到的單子叫單子棧 monad stack
  • 問題是:當單子變換的層級變深時,lift操作開始變得麻煩,當我們增加、刪除單子變換型別時,所有的lift都要做相應的改變

1. MonadIO

  • transformers函式庫提供的MonadIO型別類來自動升格IO操作
  • liftIO函式把IO操作升格到MonadIO範疇

    class Monad m => MonadIO m where
        liftIO :: IO a -> m a
    
    
    instance MonadIO IO where
        liftIO = id
    
    
    instance (MonadIO m) => MonadIO (StateT s m) where
        liftIO = lift . liftIO
    
    
    ...
    

2. MonadState和MonadReader

  • mtl函式庫中,每一個單子變換都有對應的型別類來方便使用
  • MonadState和MonadReader用來定義對應單子型別的一些通用操作

    --Control.Monad.Reader.Class
    class Monad m => MonadReader r m | m -> r where
        ask   :: m r
        local :: (r -> r) -> m a  -> m a
        reader :: (r -> a) -> m a
    
    
    instance MonadReader r ((->) r) where
        ask       = id
        local f m = m . f
        reader    = id
    
    
    --Control.Monad.State.Class
    class Monad m => MonadState s m | m -> s where
        --m必須是單子,|後的m -> s表示型別依賴,型別變數s取決於型別變數m
        get :: m s
        put :: s -> m ()
        state :: (s -> (a, s)) -> m a
    

3.型別家族 TypeFamilies

  • 型別依賴並不是唯一能描述上述型別關係的工具
  • 型別家族定義了一個滿足某些條件的型別的集合
  • 在宣告型別類時提供型別類方法定義需要的型別別名——關聯型別別名
  • 單子變換函式庫monads-tf

4. Lazy StateT 和 Strict StateT

  • 區別,單子例項宣告中的細微差別

5. Writer單子

  • 常用來構造連續的資料

不解的地方甚多,還不知道怎麼用,先把後面的看完吧

相關文章