Use cases for functor/applicative/monad instances for functions

后端 未结 3 1216
抹茶落季
抹茶落季 2021-02-01 21:07

Haskell has Functor, Applicative and Monad instances defined for functions (specifically the partially applied type (->) a

3条回答
  •  一整个雨季
    2021-02-01 21:32

    Sometimes you want to treat functions of the form a -> m b (where m is an Applicative) as Applicatives themselves. This often happens when writing validators, or parsers.

    One way to do this is to use Data.Functor.Compose, which piggybacks on the Applicative instances of (->) a and m to give an Applicative instance for the composition:

    import Control.Applicative
    import Data.Functor.Compose
    
    type Star m a b = Compose ((->) a) m b
    
    readPrompt :: Star IO String Int
    readPrompt = Compose $ \prompt -> do
        putStrLn $ prompt ++ ":"
        readLn
    
    main :: IO ()
    main = do
        r <- getCompose (liftA2 (,) readPrompt readPrompt) "write number"
        print r
    

    There are other ways, like creating your own newtype, or using ready-made newtypes from base or other libraries.

提交回复
热议问题