Вы были действительно близко.Позвольте мне добавить еще один $
для иллюстрации:
f x = (+) 5 $ (/) 8 $ x
Должно быть понятно, что выражение (+) 5
является функцией, которая принимает один числовой ввод и производит числовой вывод.То же самое относится и к выражению (/) 8
.Таким образом, вы берете любое число, введенное x
, и сначала применяете (/) 8
"функцию", а затем применяете (+) 5
"функцию".
Всякий раз, когда у вас есть цепочка функций, разделенных $
, вы можете заменить все, кроме самого правого, на .
Это означает, что если у вас есть a $ b $ c $ d
, это эквивалентно a . b . c $ d
.
f x = (+) 5 . (/) 8 $ x
На этом этапе давайте на самом деле удалить $
и вместо него скобки.
f x = ((+) 5 . (/) 8) x
Теперь должно быть ясно, что вы можете удалить трейлинг x
с обеих сторон:
f = (+) 5 . (/) 8
Это является основной идеей.Если у вас есть f x = expr x
, вы можете уменьшить его до f = expr
.Чтобы создать точечный код, вам нужно просто узнать, как большая функция состоит из более мелких функций.Частичное применение иногда необходимо для бессмысленного кода (как в этом случае, (+) 5
и (/) 8
применяются частично).Программа "pointfree" очень полезна, когда вы не хотите думать об этом;Lambdabot на канале #haskell irc использует эту программу в качестве плагина, поэтому вам даже не нужно устанавливать ее самостоятельно;просто спросите:
<DanBurton> @pl let f x = 5 + 8 / x in f
<lambdabot> (5 +) . (8 /)