最近 スタイルの質問への回答 で、私は書いた
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を使用していて、生成された値[1]がシーケンス処理する式[2]で使用されていない場合、そのコードはApplicativeスタイルに変換できます。同様に、シーケンスされた式で生成された値の1つ以上を使用する場合は、Monad
を使用する必要があり、Applicative
は同じコードを実現するのに十分な強度がありません。
たとえば、次のコードを見てみましょう。
do a <- e1
b <- e2
c <- e3
return (f a b c)
<-
の右側のどの式にも、生成された値(a
、b
、c
)は表示されないことがわかります。したがって、Applicativeコードを使用するように変換できます。考えられる変換の1つを次に示します。
f <$> e1 <*> e2 <*> e3
そして別の:
liftA3 f e1 e2 e3
一方、次のコードを例にとってみましょう。
do a <- e1
b <- e2 a
c <- e3
return (f b c)
生成された値Applicative
は後で内包表記の式で使用されるため、このコードではa
[3]を使用できません。結果を得るには、Monad
を使用する必要があります。理由を把握するために、Applicative
に因数分解してみてください。
このテーマについては、さらに興味深く有用な詳細がいくつかありますが、この経験則を提供することを目的としています。これにより、do
-の理解をざっと見て、Applicative
スタイルコードに組み込むことができるかどうかをすばやく判断できます。
[1] <-
の左側に表示されるもの。
[2] <-
の右側に表示される式。
[3]厳密に言えば、その一部はe2 a
を因数分解することで可能です。
基本的に、モナドは適用可能な関手でもあります[1]。したがって、liftM
、liftM2
などを使用していることに気付いたときはいつでも、<*>
を使用して計算を連鎖させることができます。ある意味で、適用可能なファンクターは関数に類似していると考えることができます。純粋関数f
は、f <$> x <*> y <*> z
を実行することで解除できます。
モナドと比較して、適用可能なファンクターはその引数を選択的に実行できません。すべての議論の副作用が起こります。
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
はTrue
とFalse
を順番に出力します。
[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 。モナドのParsec
ライブラリを適用可能な方法で使用する方法を示します。
実用的なファンクターの基本、実用化 BryanO'Sullivanによる。