Applicative
класса имеет <*>
оператор (обычно выраженный «ар», и эквивалентно Control.Monad.ap
для большинства Monad
с), что в сочетании с оператором <$>
(сам только инфиксный псевдонимом для fmap
) позволяет писать код как
-- f :: a -> b -> c
-- fa :: Applicative f => f a
-- fb :: Applicative f => f b
f <$> fa <*> fb :: Applicative f => f c
Если вам необходимо применить чистые аргументы, а затем использовать pure
метод Applicative
класса:
-- f :: a -> b -> c
-- a :: a
-- b :: b
f <$> pure a <*> pure b :: Applicative f => f c
Примером может быть
sumOfSquares :: Num a => a -> a -> a
sumOfSquares a b = a * a + b * b
> sumOfSquares <$> Just 1 <*> Just 2
Just 5
> sumOfSquares <$> Just 1 <*> Nothing
Nothing
> sumOfSquares <$> pure 1 <*> pure 2 :: Maybe Int
5
> sumOfSquares <$> readLn <*> readLn :: IO Int
1<ENTER>
2<ENTER>
5
Applicative f => f (a -> b -> c)
строится по f <$>
здесь, так что если вы уже что-то вроде
> let g :: IO (Int -> Int -> Int); g = undefined
Тогда вы могли бы просто использовать его как
> g <*> pure 1 <*> pure 2
Оператор <*>
имеет тип
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
так что если ваша функция имеет тип x -> y -> z
, то a ~ x
и b ~ y -> z
, поэтому повторил АП пликации <*>
(получить его?) Проходит больше аргументов в вашей завернутые функции.
Кажется, что использование 'Applicative' является более аккуратным и требует меньше скобок. Мне нравится '> $ <', предложенный @rampion, но это кажется более идиоматичным. – mgoszcz2
@ mgoszcz2 Это определенно было бы более идиоматичным, поскольку в стандартной библиотеке он использует только определенные функции. В большинстве случаев, когда вы сталкиваетесь с этой проблемой, вы уже будете работать с аппликативным, а не просто функтором (не так много полезных функций, которые также не являются аппликативными), поэтому вам не нужно беспокоиться о добавлено слишком много ограничений. Решение rampion хорошо, но строка 'f> $ < a > $ 'и' <*> '. Вероятно, я бы выбрал более легкий для ввода оператор для этого в производственном коде, если я собираюсь использовать его много. – bheklilr
bheklilr: согласовано во всех точках. Я думал об использовании '<¢>' вместо этого, но это немного жестоко на пальцах моей клавиатуры :) – rampion