我剛剛瞭解monad,並且我一直在嘗試在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
,我得到嘗試撰寫monadic函數時出錯
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)`
但是,(flatten .)
有根據ghci中鍵入Monad m => (a -> m (m b)) -> a -> m b
,那麼爲什麼會出現這種情況?
下面是函數定義(我知道我可以清理它們與=<<
和仿函數法):
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'綁定或'做'符號。 –
「'let'走出無點風格:只用它'在哪裏'它有道理,而且你會'做得更好' – Cactus