Functor, Applicative, and Monad的一个例子略有变化:
{-# LANGUAGE ApplicativeDo #-}
import Safe (readMay)
-- import Control.Applicative ((<$>), (<*>))
displayAge maybeAge =
case maybeAge of
Nothing -> putStrLn "You provided invalid input"
Just age -> putStrLn $ "In that year, you will be: " ++ show age
yearDiff futureYear birthYear = futureYear - birthYear
maybeAge fS bS = do
fI <- readMay fS
bI <- readMay bS
pure $ yearDiff fI bI
main = do
putStrLn "Please enter your birth year"
birthYearString <- getLine
putStrLn "Please enter some year in the future"
futureYearString <- getLine
displayAge $ maybeAge birthYearString futureYearString
其中 maybeAge
与 do
我用而不是
maybeAge fS bS = yearDiff <$> readMay fS <*> readMay bS
我有两个问题:
-
在这种情况下,如何检查
maybeAge
是否使用Applicative Functor语义或Monad 1? -
如果使用Applicative Functor,那么在这种情况下有什么优势?
关于:ApplicativeDo .
1 回答
我用你自己做了一个独立的例子:
另外,在最后一行中,我交换了参数,因为它们在您的示例中看起来是错误的顺序 . 我还根据@Red的评论改进了
yearDif
的定义 .以下是您的问题的答案 .
-ddump-ds
编译器开关,检查是否确实应用了applicative(和functor)操作 . 我在下面添加了几个开关,使输出更简洁 . 我还只展示有关maybeAge
功能的摘录 .Maybe
的操作具有不变的复杂性(O(1)
) - 就像monadic一样 .在original paper中,
ApplicativeDo
的作者给出了几个更复杂的monadic类型(Haxl
,Data.Seq
,解析等)的例子,允许渐近更有效的应用操作 . 见本文第6节 .