Точка стиля pointfree не только опуская имена для значений, но предпочитая имена функций. Это значительно легче сделать, когда вы используете очень маленькие определения. Конечно, любой код станет нечитаемым, если вы включите все и не будете использовать хорошие имена.
Итак, давайте начнем с вашей первоначальной функции и разделим ее на несколько меньших определений.
f xs = zipWith combine xs (inits xs)
combine x xs = (x, countWhere (< x) xs)
countWhere f xs = length (filter f xs)
Теперь мы можем легко сделать эти определения точными в удобочитаемом виде.
f = zipWith combine <*> inits
where combine = compose (,) countLessThan
compose = liftA2 (.)
countLessThan = countWhere . flip (<)
countWhere = length .: filter
(.:) = (.) . (.)
Использование имен рассудительно и предпочитая состав над приложением позволяет учитывать код на мелкие, легко понимаемых определений. Именованные параметры эквивалентны goto
для данных мощных, но лучше всего используются для создания многократно используемых структур более высокого уровня, которые легче понять и использовать правильно. Эти составные комбинаторы, такие как (.)
и <*>
, предназначены для передачи данных, которые map
, filter
и fold
предназначены для управления потоком.
с 'zipWith '= uncurry. zipWith. карри' –
Ха, да, отредактирован. –