少し等式の推論を行うことができます。まず、見てみましょうbar'
。この形で書きます
asks bar >>= \z -> return (z i)
が上記のパターンに適合するliftM
ように定義されていることがわかります。liftM f m = m >>= \a -> return (f a)
では、次のように置き換えてみましょう。
liftM ($ i) (asks bar)
それから私たちはあるfoo
として持っています
liftM show (liftM ($ i) (asks bar))
または、特に少し書き出された
liftM show . liftM ($ i) $ asks bar
それがわかっている場合liftM
、ここで作用している法律をfmap
認識する可能性がありますFunctor
fmap show . fmap ($ i) $ asks bar -- equals
fmap (show . ($ i)) $ asks bar
私は個人的に($ i)
関数として使用することの大ファンではないので、明示的なラムダとして書き直しましょう
fmap (\f -> show (f i)) (asks bar)
ここで、呼び出しサイトでasks
使用して を削除することを決定できます (つまり、型の関数として使用します)。bar
bar
bar :: FooEnv -> Int -> Int
fmap (\f -> show (bar f i)) ask
そして最後のトリックとして、 ped 関数でflip
無意味になり、使用を返すことさえできます(thanks Ørjan Johansen)fmap
asks
fmap (show . flip bar i) ask -- or even
show . flip bar i <$> ask -- or even
asks (show . flip bar i)
これがこのタスクを実行するための最も読みやすい、または優れた方法であると言っているわけではありませんが、等式の推論を使用して断片を削り取る方法を理解できます。