函数的functor/applicative/monad实例的用例

Eli*_*sky 15 haskell functional-programming

Haskell有Functor,ApplicativeMonad为函数(具体地,部分应用类型定义的实例(->) a在标准库),围绕函数组合构建的.

理解这些实例是一个很好的心灵弯曲练习,但我的问题是关于这些实例的实际用法.我很高兴听到人们使用这些实际代码的现实场景.

Red*_*edu 7

例如,涉及Functor和Applicative函数实例的常见模式(+) <$> (*2) <*> (subtract 1).当您必须使用单个值提供一系列函数时,这尤其有用.在这种情况下,上述内容相当于\x -> (x * 2) + (x - 1).虽然这非常接近,但LiftA2您可以无限期地扩展此模式.如果你有一个f函数来获取a -> a -> a -> a -> a -> b你可能想要的5个参数f <$> (+2) <*> (*2) <*> (+1) <*> (subtract 3) <*> (/2)并用一个值来提供它.就像下面的情况一样;

Prelude> (,,,,) <$> (+2) <*> (*2) <*> (+1) <*> (subtract 3) <*> (/2) $ 10
(12.0,20.0,11.0,7.0,5.0)
Run Code Online (Sandbox Code Playgroud)

编辑:感谢@Will Ness重新评论我的另一个主题的评论,这里有一个美丽的应用程序功能;

Prelude> let isAscending = and . (zipWith (<=) <*> drop 1)
Prelude> isAscending [1,2,3,4]
True
Prelude> isAscending [1,2,5,4]
False
Run Code Online (Sandbox Code Playgroud)


dan*_*iaz 4

有时您希望将形式的函数a -> m b(其中m是 an Applicative)视为Applicatives 本身。在编写验证器或解析器时经常会发生这种情况。

实现此目的的一种方法是使用Data.Functor.Compose,它搭载 和Applicative的实例(->) a,为组合m提供一个实例:Applicative

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
Run Code Online (Sandbox Code Playgroud)

还有其他方法,例如创建自己的新类型,或使用基础库或其他库中现成的 新类型