Как это будет работать?Вот подпись типа:
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Таким образом, второй аргумент здесь будет иметь тип Maybe a
, а результат должен быть типа Maybe b
.Вам нужен какой-то способ превратить a
в b
, что вы можете сделать только в том случае, если первый аргумент не Nothing
.
. Единственный способ, как что-то подобное, будет работать, если у вас есть один илибольше значений типа Maybe (a -> a)
и хотите применить любые, которые не Nothing
.Но это слишком специфично для общего определения (<*>)
.
Редактировать: Поскольку это, похоже, сценарий Maybe (a -> a)
, который вас действительно интересует, вот пара примеровиз того, что вы можете сделать с кучей значений этого типа:
Сохраните все функции и отбросьте Nothing
s, затем примените их:
applyJust :: [Maybe (a -> a)] -> a -> a
applyJust = foldr (.) id . catMaybes
Функция catMaybes
выдает список, содержащий только значения Just
, затем foldr
составляет их все вместе, начиная с функции идентификации (что вы получите, если нет функций для применения).
В качестве альтернативы, вы можете использовать функции до нахождения Nothing
, а затем выручить:
applyWhileJust :: [Maybe (a -> a)] -> a -> a
applyWhileJust (Just f:fs) = f . applyWhileJust fs
applyWhileJust (Nothing:_) = id
При этом используется та же идея, что и выше, за исключением того, что когда он находит Nothing
, он игнорирует остальную часть списка,Если хотите, вы также можете написать это как applyWhileJust = foldr (maybe (const id) (.)) id
, но это немного сложнее для чтения ...