Я написал функцию, которая применяет список функций к элементу.Применение списка функций в Haskell
applyAll :: [a -> b] -> a -> [b]
applyAll [] _ = []
applyAll (f:fs) x = (f x) : (applyAll fs x)
Есть ли лучший способ сделать это?
Я написал функцию, которая применяет список функций к элементу.Применение списка функций в Haskell
applyAll :: [a -> b] -> a -> [b]
applyAll [] _ = []
applyAll (f:fs) x = (f x) : (applyAll fs x)
Есть ли лучший способ сделать это?
Вы могли бы использовать:
applyAll l v = fmap ($ v) l
fmap
поднимает функцию над списком ввода (фактически любого функтора). $
имеет тип (a -> b) -> a -> b
, поэтому он применяет функцию к заданному значению. ($ v)
- это section, который применяет данную функцию к v
.
решение Ли является то, что я рекомендовал бы, но это читает, возможно, даже лучше:
import Control.Applicative
applyAll' fs v = fs <*> pure v
или
applyAll'' fs v = fs <*> [v]
Такого рода марок вещи сложнее, чем это необходимо, хотя: мы действительно только нужен список экземпляров Functor
, тогда как applyAll'
вводит и сразу извлекает из экземпляра Applicative
.
Эта конкретная эквивалентность действительно помогла мне задуматься о чем-то несколько месяцев назад. – dfeuer
Эта функция фактически уже существует как частный случай монадической функции:
applyAll :: [a -> b] -> a -> [b]
applyAll = sequence
Возможно, стоит отметить, что '[fb] -> f [b]' объединяется с '[a -> b] -> (a -> [b])', когда вы берете 'f', чтобы быть' (a - >) '. (Не обращайте внимания на то, что это недопустимый синтаксис, он лучше всего подходит.) – Carl
@Carl, я никогда не понимал, почему это недопустимый синтаксис. – dfeuer
Менее изворотливое решение Ли, скорее всего, будет более эффективным в некоторых контекстах, но в этом есть смысл уже быть библиотечной функцией. – dfeuer
Когда бы это не было бы лучше, что явная рекурсии альтернативы? Он более элегантный, более сжатый, более общий, возможно, более оптимизированный для оптимизации, может быть определен где угодно ad-hoc inline ... – leftaroundabout