Что я собираю из вашей подписи:
iterateM :: (Monad m) => (a -> m a) -> a -> [m a]
Это то, что n
-й элемент iterateM f x
будет действием, которое выполняется f
n
раз. Это очень близко к iterate
, я подозреваю, что мы можем реализовать это с точки зрения этого.
iterate :: (b -> b) -> b -> [b]
iterate
дает нам список b
с, и нам нужен список m a
с, поэтому я подозреваю b = m a
.
iterate :: (m a -> m a) -> m a -> [m a]
Теперь нам нужен способ преобразовать f :: a -> m a
во что-то типа m a -> m a
. К счастью, это именно то определение bind:
(=<<) :: (Monad m) => (a -> m b) -> (m a -> m b)
Итак:
\f -> iterate (f =<<) :: (a -> m a) -> m a -> [m a]
И чтобы получить наши начальные x :: a
в желаемом m a
, мы можем использовать return
:
return :: (Monad m) => a -> m a
Итак:
iterateM f x = iterate (f =<<) (return x)
Pointfreeize по вкусу.