Haskell中的ApplicativeDo pragma和Applicative函子

Haskell中的ApplicativeDo pragma和Applicative函子,haskell,monads,functor,applicative,Haskell,Monads,Functor,Applicative,略加修改的示例如下: {-# LANGUAGE ApplicativeDo #-} import Safe (readMay) -- import Control.Applicative ((<$>), (<*>)) displayAge maybeAge = case maybeAge of Nothing -> putStrLn "You provided invalid input" Just age -> p

略加修改的示例如下:

{-# 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
    是否使用Applicative Functor semantic或Monad one
  • 如果使用Applicative Functor,在这种情况下有什么优势

  • 关于:。

    我用你的例子做了一个完整的例子:

    {-# 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
    
  • 最肯定的是,这里没有加速。
    的应用操作可能具有恒定的复杂性(
    O(1)
    )-就像一元操作一样

    在中,
    ApplicativeDo
    的作者给出了几个更复杂的单元类型(
    Haxl
    Data.Seq
    、解析等)的示例,以允许渐进地更有效的应用操作。见本文件第6节


  • 关于:。还有一个旁注。您可以使用
    yearDiff=subtract
    {-# 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
    
    $ 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)
    ...