То, что у вас есть, это
prod x y z t = x * y * z * t
= (x * y * z) * t
= (*) (x * y * z) t
Следовательно, на Это сокращение (где мы заменяем foo x = bar x
на foo = bar
)
prod x y z = (*) (x * y * z)
= (*) ( (x * y) * z )
= (*) ( (*) (x * y) z )
= ((*) . (*) (x * y)) z
, так чтоЭто снова сокращение,
prod x y = (*) . (*) (x * y)
Здесь (.)
- оператор композиции функции, определяемый как
(f . g) x = f (g x)
То, о чем вы спрашиваете, известно как стиль без точек.«Точка без» означает «без явного упоминания [подразумеваемых] аргументов» (здесь «точка» - это жаргон математического выражения «аргумент»).
«Карринг» - это ортогональный вопрос, хотя Хаскель - карри language облегчает написание таких определений - и частичных применений, показанных в ответе Виллема.«Curry» означает, что функции принимают свои аргументы по одному, поэтому легко частично применить функцию к значению.
Мы можем продолжить процесс извлечения последнего аргумента из , поэтомуэто может быть устранено путем сокращения eta в дальнейшем.Но обычно это быстро приводит к все более запутанному коду, например prod = ((((*) .) . (*)) .) . (*)
.
Это потому, что письменный код - это одномерное кодирование структуры двумерного (или даже многомерного) вычислительного графа, присущей только ему,
prod =
/
*
/ \
*
/ \
<-- *
\
Вы можете поэкспериментировать с ним здесь .Например, если бы (*)
было ассоциативно правым, мы получили бы еще более запутанный код
\x y z t -> x * (y * (z * t))
==
(. ((. (*)) . (.) . (*))) . (.) . (.) . (*)
, представляющий столь же отчетливо выглядящую, слегка переставленную структуру графика
/
<-- *
\ /
*
\ /
*
\