Нужна помощь, чтобы понять, как работает эта функциональная композиция - PullRequest
0 голосов
/ 03 марта 2019

Я могу понять эту строку кода без проблем

let f s = filter (isDigit.head) (groupBy (on (==) isDigit) s)

, когда я звоню f "123abc345", он возвращает ["123", "345"]

Но мне трудно понять, почему следующееСтрока кода такая же

let g = filter (isDigit.head) . groupBy (on (==) isDigit)

Как работает эта композиция?Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

Во-первых, ваш код для справки:

let f s = filter (isDigit.head)  (groupBy (on (==) isDigit) s)
let g   = filter (isDigit.head) . groupBy (on (==) isDigit)

(я немного отформатировал его, чтобы подчеркнуть сходство.)

Чтобы помочь нам немного, давайте теперь определим некоторые синонимыдля функций в ваших определениях:

let whereFirstIsDigit = filter (isDigit.head)
let groupByDigit      = groupBy (on (==) isDigit))

Теперь мы можем переписать исходные функции следующим образом:

let f s = whereFirstIsDigit  (groupByDigit s)
let g   = whereFirstIsDigit . groupByDigit

Теперь давайте посмотрим, что здесь происходит.f принимает s, передает его в groupByDigit, а затем передает результат этого в whereFirstIsDigit.Но состав функции (скажем) x . y определен как функция, которая передает свой ввод в y, а затем передает результат в x!Итак, две функции одинаковы.

0 голосов
/ 03 марта 2019

Оператор композиции функции . определяется следующим образом:

(.) f g = \x -> f (g x)

Или то же самое в инфиксной форме:

f . g = \x -> f (g x)

На английском языке это можно выразить так: композиция из двух функций f и g - это другая функция, которая принимает аргумент x, передает его в функцию g, а затем передает возвращаемое значение g в функцию f

Если вы посмотрите на свой первый фрагмент:

let f s = filter (isDigit.head) (groupBy (on (==) isDigit) s)

Если ваш косоглазие достаточно сложное, вы можете увидеть, что это функция, которая принимает аргумент s, передает его в функцию groupBy (on (==) isDigit), а затем передает возвращаемое значение в функцию filter (isDigit.head)

, которая, согласно моему объяснению выше, может быть выражена в виде комбинации двух функций - filter (isDigit.head) и groupBy (on (==) isDigit), что является вашим вторымфрагмент.

...