簡體   English   中英

Haskell中的ApplicativeDo編譯指示和Applicative函子

[英]ApplicativeDo pragma and Applicative Functor in Haskell

來自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

其中maybeAgedo我用來代替

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

我有兩個問題:

  1. 在這種情況下,我該如何檢查maybeAge使用Applicative Functor語義或Monad?
  2. 如果使用Applicative Functor,在這種情況下有什么優勢?

關於: ApplicativeDo

我從您身上做了一個完整的例子:

{-# 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

另外,在最后一行,我交換了參數,因為它們在示例中的順序似乎不正確。 我也yearDif的注釋改進了yearDif定義。

這是您問題的答案。

  1. 您可以按照《 GHC 用戶指南》中的建議(即使用-ddump-ds編譯器開關)檢查是否確實應用了應用(和函子)操作。 我在下面添加了幾個開關,以使輸出更簡潔。 我也只顯示有關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. 最肯定的是,這里沒有提速。 適用的操作符Maybe具有恆定的復雜度( O(1) )-就像單子步操作符一樣。

    原始論文中ApplicativeDo的作者給出了一些更復雜的單子類型( HaxlData.Seq ,解析等)的Data.Seq ,從而使漸近地更有效地進行了運算。 請參閱本文的第6節。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM