Вы можете применить комбинатор B (т.е. (f . g) x = f (g x)
) там:
function2 a b c = (a * b) + c
function2 a b c = ((*) a b) + c -- operator sectioning
function2 a b c = (+) ((*) a b) c -- operator sectioning once more
= (+) (((*) a) b) c -- explicit parentheses
= ((+) . ((*) a)) b c -- B combinator
= ((.) (+) ((*) a)) b c -- operator sectioning
= ((.) (+) . (*)) a b c -- B combinator
Действительно, типы одинаковы:
> :t let function2 a b c = (a * b) + c in function2
let function2 a b c = (a * b) + c in function2
:: Num a => a -> a -> a -> a
> :t ((.) (+) . (*))
((.) (+) . (*)) :: Num b => b -> b -> b -> b
Мы работаем, выводя аргументы один за другим в правильном порядке, чтобы в итоге получить
function2 a b c = (......) a b c
так что eta-сжатие может быть применено, чтобы избавиться от явных аргументов,
function2 = (......)
Наши инструменты , которые мы можем применить в обоих направлениях ,
S a b c = (a c) (b c) = (a <*> b) c
K a b = a = const a b
I a = a = id a
B a b c = a (b c) = (a . b) c
C a b c = a c b = flip a b c
W a b = a b b = join a b
U a = a a -- not in Haskell: `join id` has no type
Там также (f =<< g) x = f (g x) x = join (f . g) x
.
Еще несколько полезных шаблонов, которые появляются, когда мы некоторое время работаем с pointfree:
((f .) .) g x y = f (g x y)
(((f .) .) .) g x y z = f (g x y z)
.....
((. g) . f) x y = f x (g y)
((. g) . f . h) x y = f (h x) (g y)
(обновление.) Во втором примере рядом с началом есть ошибка, после которой все следующие шаги становятся недействительными:
function3 a b = a `div` (g b)
function3 a b = -- `div` a (g b) -- wrong syntax, you meant
div a (g b)
function3 a b = -- (`div` a) (g b) -- wrong; it is
(a `div`) (g b) --operator sectioning
function3 a b = ((a `div`) . g) b --B combinator
function3 a = (div a . g) --eta conversion; back with plain syntax
function3 a = (.) (div a) g --operator sectioning
function3 a = flip (.) g (div a) --definition of flip
function3 a = (flip (.) g . div) a --B combinator
function3 = (flip (.) g . div) --eta conversion
= (.) (flip (.) g) div --operator section
Так что да, некоторые шаги были в правильном направлении.