Как составить двоичную функцию с унарной функцией?
Мне кажется, что я пропускаю что-то совершенно очевидное здесь, но каков правильный способ (если есть) использовать точечную нотацию для составления двоичной функции и унарной функции? Например, следующий код компилируется:
sortedAppend :: (Ord a) -> [a] -> [a] -> [a]
sortedAppend xs ys = sort $ xs ++ ys
но следующий код не компилируется:
sortedAppend :: (Ord a) -> [a] -> [a] -> [a]
sortedAppend = sort . (++)
Можем ли мы составить (++)
с sort
(в порядке, указанном выше)? Если да, то как?
Ответы
Ответ 1
Я не думаю, что любое из этих решений (мое или других) - это довольно, но я предпочитаю....
let sortedAppend = (sort .) . (++)
Причина, по которой я предпочитаю это, - это то, что мне легко думать... Если вы проигнорируете скобки, вам в основном нужно добавить дополнительный (.) для каждого параметра
f . g --one parameter
f . . g --two params
f . . . g --three params
что имеет смысл, так как g x
возвращает функцию с входами N-1....
.... но те необходимые парнеры делают это настолько уродливым....
((f .) .) . g
Ответ 2
Вы можете использовать "сова-оператор" (иногда я называю breast.operator тоже):
Prelude> :t (.).(.)
(.).(.) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c
НО: Я не думаю, что вам следует - то, что вы написали, очень читаемо - используя это:
sortedAppend = ((.).(.)) sort (++)
не является IMO
PS: да, вы могли бы сделать
(.:.) = (.).(.)
sortedAppend = sort .:. (++)
но все же.... не удобоваримый
PPS: Я только узнал, что этот оператор определяется как (.:)
в пакете под названием pointless-fun ^^
Ответ 3
Просто для полноты позвольте на самом деле принять ваш пример и постепенно сделать его точным.
Во-первых, запомните (f . g) x = f (g x)
. Тогда существует Eta-редукция (\x -> f x) ≡ f
. Последняя полезная вещь - раздел .
Используя эти правила, мы можем сделать следующее:
sortedAppend xs ys = sort $ xs ++ ys -- original function
sortedAppend xs ys = sort (xs ++ ys) -- remove $
sortedAppend xs ys = sort ((++) xs ys) -- prefix application of ++
sortedAppend xs ys = (sort . ((++) xs)) ys -- definition of composition
sortedAppend xs = sort . (++) xs -- eta reduction
sortedAppend xs = (sort .) ((++) xs) -- operator section
sortedAppend xs = ((sort .) . (++)) xs -- definition of composition
sortedAppend = (sort .) . (++) -- eta reduction
Ответ 4
Я не думаю, что Id лично рекомендует добавлять зависимости для таких вещей, но есть и
(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
в Data.Composition
в пакете composition
.