Как выполнить цикл по списку монадических значений?

#haskell

Вопрос:

Допустим, у меня есть список 3 ценностей: es = [MyMonad 33, MyMonad 55, MyMonad 88] . Тогда я бы выступил

 do v1 <- funcReturningMyMonad (es !! 0)
   v2 <- funcReturningMyMonad (es !! 1)
   v3 <- funcReturningMyMonad (es !! 2)
   funcTakingListOfInts [v1,v2,v3]
 

Моя проблема в том, что я хотел бы каким-то образом добиться такого поведения для списка произвольной длины n . В приведенном выше случае n было 3 . Я думал о том, чтобы звонить (>>=) последовательно по списку, но это не сходится. Как бы вы добились такого поведения?

Типы функций:

 funcReturningMyMonad :: MyMonad Int -> MyMonad Int
funcTakingListOfInts :: [Int] -> MyMonad Int
 

Комментарии:

1. Я переименовал ваш вопрос, пожалуйста, дайте мне знать, если вы согласны с переименованием.

Ответ №1:

С

 funcReturningMyMonad :: MyMonad Int -> MyMonad Int
 

мы можем использовать

 mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)  
 

для первой части, которая в нашем случае будет

  (MyMonad Int -> MyMonad Int) -> [MyMonad Int] -> MyMonad [Int]
 

затем мы можем использовать оператор привязки для подачи funcTakingListOfInts заявки, чтобы вы получили:

 (mapM funcReturningMyMonad es) >>= funcTakingListOfInts
 

Комментарии:

1. Э-э-э, я думаю, что это оно!! Но я пытаюсь понять это rn — можете ли вы сказать мне, как можно mapM принять funcReturningMyMonad , когда ожидаемый тип есть (a -> m b) , а тип funcReturningMyMonad есть m b -> m b -я имею в виду funcReturningMyMonad возвращает тот же монадический тип, который он принимает в качестве аргумента?

2. Well a -это переменная типа, которая может быть любого типа, поэтому нет никаких проблем в том, чтобы она была того же типа, m b что и . Или более простой пример: fst :: (a, b) -> a . Это все еще можно применить к (1, 2) :: (Int, Int) с a == b , нет необходимости в том, чтобы они были разными.

3. В этом, конечно, есть смысл, спасибо! Я ценю вашу помощь!