Я новичок в Хаскеле. Это может быть глупым вопросом.
Поскольку класс типов Applicative имеет функцию apply , которая принимает функции и данные в одном контексте. Почему он не может быть другим и более общим.
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
Почему мы не можем написать что-то подобное
class Functor f => Applicative f where
(<*>) :: Functor g => g (a -> b) -> f a -> g (f b)
(<*>) gab fa = fmap (\g -> fmap g fa) gab
(<<*>>) :: Functor g => (g (f a) -> f a) -> g (a -> b) -> f a -> f b
(<<*>>) peelOuter gab fa = peelOuter $ gab <*> fa
(>>*<<) :: Functor g => (g (f a) -> g a) -> g (a -> b) -> f a -> g b
(>>*<<) cleanInner gab fa = cleanInner $ gab <*> fa
Это можно использовать как показано ниже
-- Extract List from maybe
elfm :: Maybe [a] -> [a]
elfm Nothing = []
elfm (Just xs) = xs
-- Fuse List elements in Maybe []
flem :: Monoid a => Maybe [a] -> Maybe a
flem Nothing = mempty
flem (Just xs) = Just $ foldl (<>) mempty xs
Just (*2) <*> [1,2,3,4]
-- Just [2,4,6,8]
(<<*>>) elfm (Just (*2)) [1,2,3,4]
-- [2,4,6,8]
(>>*<<) flem (Just (++ "Haskell")) ["Hello, "]
-- Just "Hello, Haskell"
И я прочитал, что весь смысл наличия Applicative - это недостаток Functors, поднимающих функции с несколькими аргументами. Правильно ли это?
И я не думаю, что приложение функции соответствует ожиданиям.
add :: Num a => a -> a -> a
add a b = a + b
-- I want to apply [1,2,3] as First arguments and [4,5,6] as 2nd arguments.
-- Like add 1 4, add 2 4, add 3 6
-- But it is give all possibilities of combinations like a tree
-- <*>
-- (+1) (+2) (+3)
-- (1+4)(1+5)(1+6) (2+4)(2+5)(2+6) (3+4)(3+5)(3+6)
А также они сравниваются с пакетной обработкой, но не приведен вполне реальный пример из жизни. Пожалуйста, приведите пример для этого.