потому что с пониманием для чего они нужны функция
ap :: Monad m => m (a -> b) -> m a -> m b
ap mf mx = do
f <- mf
x <- mx
return $ f x
пишется просто элементарно без всяких постзнаний
типа логика тут простая
у нас есть запаковання функция, и запакованный аргумент, а нужен запакованный результат
значит распаковываем, применяем, а потом запаковываем