Я могу понять основы безточечных функций в Haskell:
addOne x = 1 + x
Поскольку мы видим 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 average = liftM2 ((/) . realToFrac) sum genericLength
работает. - person Ørjan Johansen   schedule 31.10.2015ap
реализацию экземпляра Monad для функций - person Bergi   schedule 31.10.2015ap
можно определить как(. ((. (return .)) . (>>=))) . (>>=)
. :-) - person awllower   schedule 10.03.2018