简体   繁体   English

Haskell中的ApplicativeDo编译指示和Applicative函子

[英]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 其中maybeAgedo我用来代替

maybeAge fS bS = yearDiff <$> readMay fS <*> readMay bS

I have the 2 questions: 我有两个问题:

  1. How can I check does maybeAge use Applicative Functor semantic or Monad one in this case? 在这种情况下,我该如何检查maybeAge使用Applicative Functor语义或Monad?
  2. What is an advantage in that case if Applicative Functor used? 如果使用Applicative Functor,在这种情况下有什么优势?

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. 这是您问题的答案。

  1. 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) ... 
  2. 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的作者给出了一些更复杂的单子类型( HaxlData.Seq ,解析等)的Data.Seq ,从而使渐近地更有效地进行了运算。 See Section 6 of the paper. 请参阅本文的第6节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM