#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. В этом, конечно, есть смысл, спасибо! Я ценю вашу помощь!