Как составить двоичную функцию с унарной функцией?

Мне кажется, что я пропускаю что-то совершенно очевидное здесь, но каков правильный способ (если есть) использовать точечную нотацию для составления двоичной функции и унарной функции? Например, следующий код компилируется:

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.