Ich habe gerade etwas über Monaden gelernt, und ich habe versucht, viele der Funktionen in Control.Monad zu implementieren. Ich habe gerade ap
, aber ich kann es nicht funktionieren. Ich machte eine Funktion almostAp :: Monad m => m (a -> b) -> m a -> m (m b)
, und ich habe versucht, es mit einer anderen Funktion, die ich machte, flatten :: Monad m => m (m b) -> m b
zu komponieren. Das Problem ist, wenn ich versuche, ap = flatten . almostAp
zu verwenden, ichFehler beim Versuch, monadische Funktionen zu erstellen
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)`
Aber (flatten .)
Typ Monad m => (a -> m (m b)) -> a -> m b
hat nach GHCI, also warum geschieht dies?
Hier sind die Funktionsdefinitionen (ich weiß, ich sie mit =<<
reinigen kann und die Funktors Gesetze):
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)
Sie scheinen sehr auf Point-Free-Stil, der Ihren Code ziemlich schwer zu lesen macht (und ich kann mir vorstellen, ziemlich schwer zu schreiben, auch!) Haben Sie keine Angst vor "Let' Bindings" oder "Do" Notation. –
"Lass uns vom punktfreien Stil gehen: benutze es nur' wo' es macht Sinn, und du wirst besser "tun" – Cactus