モナドについて知りましたが、私は多くの関数をControl.Monadに実装しようとしていました。私はちょうどap
に行ったが、私はそれを働かせることはできない。私は関数almostAp :: Monad m => m (a -> b) -> m a -> m (m b)
を作って、私が作った別の関数flatten :: Monad m => m (m b) -> m b
でそれを作ろうとしました。私はap = flatten . almostAp
を使用しようとすると問題が(flatten .)
がGHCiのに応じてMonad m => (a -> m (m b)) -> a -> m b
型を持ち、私はモナディック関数を作成しようとするとエラーが発生する
Occurs check: cannot construct the infinite type: m ~ (->) (m a)
Expected type: m (a -> b) -> m a -> m a -> m b
Actual type: m (a -> b) -> m a -> m (m b)
In the second argument of ‘(.)’, namely ‘almostAp’
In the expression: (flatten . almostAp)`
を得る。しかし、であるので、これはなぜ起こるのでしょうか?ここで
は関数定義されている(私は=<<
でそれらをクリーンアップすることができます知っているとファンクタの法則):
almostAp :: Monad m => m (a -> b) -> m a -> m (m b)
almostAp = (flip (\x -> fmap ($x))) . (fmap (flip (>>=))) . (fmap (return .))
flatten :: Monad m => m (m a) -> m a
flatten = (>>= id)
あなたはコードを読みにくくするポイントフリーのスタイルに非常に敏感であるようです(想像もできませんが、書くのは難しいでしょう)。 'let'バインディングや' do'を恐れてはいけません。表記 –
"ポイントフリーのスタイルの" let "を使用してください:それは理に適っていて、それをより良く使うでしょう" – Cactus