я в состоянии понять основы точечных свободных функций в Haskell:Понимание `ap` в функции точечным бесплатно в Haskell
addOne x = 1 + x
Как мы видим, х по обе стороны уравнения, мы упрощаем это:
addOne = (+ 1)
Невероятно получается, что функции, где тот же самый аргумент используется дважды в разных частях можно записать точку бесплатно!
Позвольте мне взять в качестве основного примера функцию average
записать в виде:
average xs = realToFrac (sum xs)/genericLength xs
Это может показаться невозможным, чтобы упростить xs
, но http://pointfree.io/ выходит с:
average = ap ((/) . realToFrac . sum) genericLength
Это работает.
Насколько я понимаю, это указывает, что average
такое же, как вызов ap
на две функции, состав (/) . realToFrac . sum
и genericLength
К сожалению, функция ap
не имеет никакого смысла вообще для меня, Документах http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Monad.html#v:ap состояние:
ap :: Monad m => m (a -> b) -> m a -> m b
In many situations, the liftM operations can be replaced by uses of ap,
which promotes function application.
return f `ap` x1 `ap` ... `ap` xn
is equivalent to
liftMn f x1 x2 ... xn
Но написание:
let average = liftM2 ((/) . realToFrac . sum) genericLength
не работает, (дает сообщение об ошибке очень длинного типа, спрашивает, и я его включу), поэтому я не понимаю, что говорят документы.
Как работает выражение ap ((/) . realToFrac . sum) genericLength
? Не могли бы вы объяснить ap
проще, чем документы?
'let средний = liftM2 ((/). НастоящийToFrac) сумма обобщенныйLength' works. –
@ ØrjanJohansen Интересно, не могли бы вы объяснить, почему в ответ? – Caridorc
Взгляните на реализацию «ap» экземпляра Monad для функций. – Bergi