What is indexed monad?

前端 未结 5 525
猫巷女王i
猫巷女王i 2020-11-27 09:47

What is indexed monad and the motivation for this monad?

I have read that it helps to keep track of the side effects. But the type signature and documentation doesn\

5条回答
  •  独厮守ぢ
    2020-11-27 10:19

    As a simple scenario, assume you have a state monad. The state type is a complex large one, yet all these states can be partitioned into two sets: red and blue states. Some operations in this monad make sense only if the current state is a blue state. Among these, some will keep the state blue (blueToBlue), while others will make the state red (blueToRed). In a regular monad, we could write

    blueToRed  :: State S ()
    blueToBlue :: State S ()
    
    foo :: State S ()
    foo = do blueToRed
             blueToBlue
    

    triggering a runtime error since the second action expects a blue state. We would like to prevent this statically. Indexed monad fulfills this goal:

    data Red
    data Blue
    
    -- assume a new indexed State monad
    blueToRed  :: State S Blue Red  ()
    blueToBlue :: State S Blue Blue ()
    
    foo :: State S ?? ?? ()
    foo = blueToRed `ibind` \_ ->
          blueToBlue          -- type error
    

    A type error is triggered because the second index of blueToRed (Red) differs from the first index of blueToBlue (Blue).

    As another example, with indexed monads you can allow a state monad to change the type for its state, e.g. you could have

    data State old new a = State (old -> (new, a))
    

    You could use the above to build a state which is a statically-typed heterogeneous stack. Operations would have type

    push :: a -> State old (a,old) ()
    pop  :: State (a,new) new a
    

    As another example, suppose you want a restricted IO monad which does not allow file access. You could use e.g.

    openFile :: IO any FilesAccessed ()
    newIORef :: a -> IO any any (IORef a)
    -- no operation of type :: IO any NoAccess _
    

    In this way, an action having type IO ... NoAccess () is statically guaranteed to be file-access-free. Instead, an action of type IO ... FilesAccessed () can access files. Having an indexed monad would mean you don't have to build a separate type for the restricted IO, which would require to duplicate every non-file-related function in both IO types.

提交回复
热议问题