簡體   English   中英

你如何使用Control.Applicative來編寫更干凈的Haskell?

[英]How do you use Control.Applicative to write cleaner Haskell?

在最近的一個風格問題的答案中 ,我寫道

main = untilM (isCorrect 42) (read `liftM` getLine)

isCorrect num guess =
  case compare num guess of
    EQ -> putStrLn "You Win!" >> return True
    ...

Martijn幫助提出了替代方案:

main = untilM (isCorrect 42) (read <$> getLine)

EQ -> True <$ putStrLn "You Win!"

使用Control.Applicative中的抽象可以使Haskell代碼中的哪些常見模式更清晰? 有效使用Control.Applicative時要記住哪些有用的經驗法則?

回答你的問題有很多話要說,但是,既然你問過,我會提供這個“經驗法則”。

如果您正在使用do -notation,並且您正在排序的表達式[2]中未使用生成的值[1],那么該代碼可以轉換為Applicative樣式。 同樣,如果在排序的表達式中使用一個或多個生成的值,則必須使用MonadApplicative不足以實現相同的代碼。

例如,讓我們看看以下代碼:

do a <- e1
   b <- e2
   c <- e3
   return (f a b c)

我們看到<-沒有任何表達式出現任何生成的值( abc )。 因此,我們可以將其轉換為使用Applicative代碼。 這是一個可能的轉變:

f <$> e1 <*> e2 <*> e3

另一個:

liftA3 f e1 e2 e3

另一方面,以這段代碼為例:

do a <- e1
   b <- e2 a
   c <- e3
   return (f b c)

此代碼不能使用Applicative [3],因為稍后在理解中的表達式中使用生成的值a 這必須使用Monad來達到其結果 - 嘗試將其納入Applicative以了解原因。

有關於這個問題的另外一些有趣和有用的信息,但是,我只打算給你這個經驗法則,讓你可以掠過do -comprehension並很快確定它是否可以被分解成Applicative樣式代碼。

[1]出現在左邊的那些<-

[2]表達式出現在<-的右側。

[3]嚴格來說,部分內容可以通過分解e2 a

基本上,monad也是應用函子[1]。 因此,每當您發現自己使用liftMliftM2等時,您可以使用<*>將計算鏈接在一起。 從某種意義上說,你可以認為applicative functor與函數類似。 可以通過執行f <$> x <*> y <*> z來提升純函數f

與monad相比,applicative functor無法有選擇地運行其參數。 所有論點的副作用都將發生。

import Control.Applicative

ifte condition trueClause falseClause = do
  c <- condition
  if c then trueClause else falseClause

x = ifte (return True) (putStrLn "True") (putStrLn "False")

ifte' condition trueClause falseClause = 
  if condition then trueClause else falseClause

y = ifte' <$> (pure True) <*> (putStrLn "True") <*> (putStrLn "False")

x僅輸出True ,而y依次輸出TrueFalse

[1] Typeclassopedia 強烈推薦。

[2] http://www.soi.city.ac.uk/~ross/papers/Applicative.html 雖然這是一篇學術論文,但並不難理解。

[3] http://learnyouahaskell.com/functors-applicative-functors-and-monoids#applicative-functors 很好地解釋了這筆交易。

[4] http://book.realworldhaskell.org/read/using-parsec.html#id652399 顯示monadic Parsec庫如何以應用方式使用。

請參閱Bryan O'Sullivan的實際工作,了解應用仿函數的基礎知識

暫無
暫無

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

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