Я работал над простой задачей Leetcode в Haskell: Максимальное количество Pos и Neg Integer:
-- First solution
maximumCount :: [Int] -> Int
maximumCount = liftM2 max (length . filter (> 0)) (length . filter (< 0))
-- Custom combinator that's ALMOST the Psi combinator
-- abcde.a(b(ce)(b(de))
myCombinator :: (c -> c -> d) -> (a -> b -> c) -> a -> a -> b -> d
myCombinator f g x y z = f (g x z) (g y z)
-- Second solution
maximumCount' :: [Int] -> Int
maximumCount' = myCombinator max (length .: filter) (> 0) (< 0)
Мне не удалось найти существующий комбинатор, который ведет себя таким образом. Но я уверен, что его можно определить, объединив существующие комбинаторы. Я все еще новичок в комбинаторной логике, поэтому, возможно, мне неизвестен существующий эквивалент или, возможно, методология получения комбинаторного написания.
Я попытался написать функцию для объединения аргументов функции так, чтобы они имели правильную форму для функции on
, но мне не удалось получить правильное определение.
Это выглядит как on
работа над считывателем (->) a
, поэтому следующее должно работать. Обратите внимание, что я начал с того, что перенес бинарный оператор в программу чтения и вызвал on
:
myCombinator op f = on (liftA2 op) f
а затем упростил результат:
import Control.Applicative
import Data.Function
myCombinator :: (c -> c -> d) -> (a -> b -> c) -> a -> a -> b -> d
myCombinator = on . liftA2
Спасибо, это именно то, что я искал. Я верю, что в комбинаторной логике эквивалентом
on . liftA2
будетΨBΦ
.