[英]ApplicativeDo pragma and Applicative Functor in Haskell
An example from Functor, Applicative, and Monad slightly changed: 来自Functor,Applicative和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
where maybeAge
with do
I used instead of 其中
maybeAge
与do
我用来代替
maybeAge fS bS = yearDiff <$> readMay fS <*> readMay bS
I have the 2 questions: 我有两个问题:
maybeAge
use Applicative Functor semantic or Monad one in this case? maybeAge
使用Applicative Functor语义或Monad? About: ApplicativeDo . 关于: ApplicativeDo 。
I made a self-contained example out of yours: 我从您身上做了一个完整的例子:
{-# LANGUAGE ApplicativeDo #-}
import Text.Read (readMaybe)
displayAge :: Maybe Int -> IO ()
displayAge maybeAge =
case maybeAge of
Nothing -> putStrLn "You provided invalid input"
Just age -> putStrLn $ "In that year, you will be: " ++ show age
yearDiff :: Int -> Int -> Int
yearDiff = (-)
maybeAge :: String -> String -> Maybe Int
maybeAge fS bS = do
fI <- readMaybe fS
bI <- readMaybe bS
pure $ yearDiff fI bI
main :: IO ()
main = do
putStrLn "Please enter your birth year"
birthYearString <- getLine
putStrLn "Please enter some year in the future"
futureYearString <- getLine
displayAge $ maybeAge futureYearString birthYearString
Also, in the last line, I swapped the arguments, as they appear to be in the wrong order in your example. 另外,在最后一行,我交换了参数,因为它们在示例中的顺序似乎不正确。 Also I improved
yearDif
definition as per @Redu's comment. 我也
yearDif
的注释改进了yearDif
定义。
Here are the answers on your questions. 这是您问题的答案。
You can check that applicative (and functor) operations are indeed applied, following the advice in the GHC's User Guide , namely, using the -ddump-ds
compiler switch. 您可以按照《 GHC 用户指南》中的建议(即使用
-ddump-ds
编译器开关)检查是否确实应用了应用(和函子)操作。 I add a couple more switches below to make the output more succinct. 我在下面添加了几个开关,以使输出更简洁。 I also show only excerpt concerning the
maybeAge
function. 我也只显示有关
maybeAge
函数的摘录。
$ ghc appdo.hs -ddump-ds -dsuppress-type-applications -dsuppress-module-prefixes [1 of 1] Compiling Main ( appdo.hs, appdo.o ) ==================== Desugar (after optimization) ==================== Result size of Desugar (after optimization) = {terms: 75, types: 75, coercions: 0, joins: 0/0} ... -- RHS size: {terms: 17, types: 13, coercions: 0, joins: 0/0} maybeAge :: String -> String -> Maybe Int [LclId] maybeAge = \\ (fS_a1h3 :: String) (bS_a1h4 :: String) -> <*> $fApplicativeMaybe (fmap $fFunctorMaybe (\\ (fI_a1h5 :: Int) (bI_a1h6 :: Int) -> yearDiff fI_a1h5 bI_a1h6) (readMaybe $fReadInt fS_a1h3)) (readMaybe $fReadInt bS_a1h4) ...
Most certainly, no speedup is gained here. 最肯定的是,这里没有提速。 Applicative opertaions for
Maybe
have constant complexity ( O(1)
) — just like the monadic ones. 适用的操作符
Maybe
具有恒定的复杂度( O(1)
)-就像单子步操作符一样。
In the original paper , the authors of ApplicativeDo
give several examples of more sophisticated monadic types ( Haxl
, Data.Seq
, parsing, etc.) allowing for asymptotically more efficient applicative operations. 在原始论文中 ,
ApplicativeDo
的作者给出了一些更复杂的单子类型( Haxl
, Data.Seq
,解析等)的Data.Seq
,从而使渐近地更有效地进行了运算。 See Section 6 of the paper. 请参阅本文的第6节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.