Какие интересные варианты использования функций высшего порядка? - PullRequest
33 голосов
/ 26 апреля 2011

В настоящее время я прохожу курс функционального программирования, и меня довольно удивляет концепция функций и функций высшего порядка как граждан первого класса.Однако я пока не могу придумать много практически полезных, концептуально удивительных или просто интересных функций высшего порядка.(Помимо типичных и довольно скучных функций map, filter и т. Д.).

Знаете ли вы примеры таких интересных функций?

Может быть, функции, которые возвращают функции, функции, которые возвращают списки функций (?) И т. Д.

Я был бы признателен за примеры в Haskell, который является языком, который я изучаю в настоящее время:)

Ответы [ 14 ]

3 голосов
/ 26 апреля 2011

Вот небольшой перефразированный код фрагмент:

rays :: ChessPieceType -> [[(Int, Int)]]
rays Bishop = do
  dx <- [1, -1]
  dy <- [1, -1]
  return $ iterate (addPos (dx, dy)) (dx, dy)
...  -- Other piece types

-- takeUntilIncluding is an inclusive version of takeUntil
takeUntilIncluding :: (a -> Bool) -> [a] -> [a]

possibleMoves board piece = do
  relRay <- rays (pieceType piece)
  let ray = map (addPos src) relRay
  takeUntilIncluding (not . isNothing . pieceAt board)
    (takeWhile notBlocked ray)
  where
    notBlocked pos =
      inBoard pos &&
      all isOtherSide (pieceAt board pos)
    isOtherSide = (/= pieceSide piece) . pieceSide

Здесь используются несколько функций «высшего порядка»:

iterate :: (a -> a) -> a -> [a]
takeUntilIncluding  -- not a standard function
takeWhile :: (a -> Bool) -> [a] -> [a]
all :: (a -> Bool) -> [a] -> Bool
map :: (a -> b) -> [a] -> [b]
(.) :: (b -> c) -> (a -> b) -> a -> c
(>>=) :: Monad m => m a -> (a -> m b) -> m b

(.) - это . оператор, а (>>=) - это do -обозначение «оператор разрыва строки».

При программировании на Haskell вы просто используете их.Когда у вас нет функций высшего порядка, вы понимаете, насколько они невероятно полезны.

3 голосов
/ 26 апреля 2011

Здесь есть несколько примеров: http://www.haskell.org/haskellwiki/Higher_order_function

Я также рекомендовал бы эту книгу: http://www.cs.nott.ac.uk/~gmh/book.html, которая является отличным введением во все Haskell и охватывает функции высшего порядка.

Функции высшего порядка часто используют аккумулятор, поэтому его можно использовать при формировании списка элементов, которые соответствуют заданному правилу из большого списка.

2 голосов
/ 28 апреля 2011

Как уже упоминалось, Javascript поддерживает некоторые функции высшего порядка, включая эссе от Джоэла Спольски .Марк Джейсон Доминус написал целую книгу под названием Perl высшего порядка ;исходный текст книги доступен для бесплатной загрузки в различных тонких форматах, включая PDF .

Начиная с версии Perl 3 Perl поддерживает функциональность, больше напоминающую Lisp, чем C, нотолько в Perl 5 была доступна полная поддержка замыканий и всего, что из этого следует.И ни одна из первых реализаций Perl 6 была написана на Haskell, что оказало большое влияние на прогресс в разработке этого языка.

Примеры подходов функционального программирования в Perl появляются в повседневном программировании, особенно с map и grep:

@ARGV    = map { /\.gz$/ ? "gzip -dc < $_ |" : $_ } @ARGV;

@unempty = grep { defined && length } @many;

Поскольку sort также допускает замыкание, шаблон map/sort/map является очень распространенным:

@txtfiles = map { $_->[1] }
            sort { 
                    $b->[0]  <=>     $a->[0]
                              ||
                 lc $a->[1]  cmp  lc $b->[1]
                              ||
                    $b->[1]  cmp     $a->[1]
            }
            map  { -s => $_ } 
            grep { -f && -T }
            glob("/etc/*");

или

@sorted_lines = map { $_->[0] }
                sort {
                     $a->[4] <=> $b->[4] 
                             ||
                    $a->[-1] cmp $b->[-1]
                             ||
                     $a->[3] <=> $b->[3]
                             ||
                     ...
                }
                map { [$_ => reverse split /:/] } @lines;

Функция reduce упрощает взлом списков без зацикливания:

$sum = reduce { $a + $b } @numbers;

$max = reduce { $a > $b ? $a : $b } $MININT, @numbers;

Это намного больше, но это только вкус.Замыкания упрощают создание генераторов функций, написание собственных функций высшего порядка, а не только использование встроенных функций.Фактически, одна из наиболее распространенных моделей исключений,

try {
   something();
} catch {
   oh_drat();
};

, является , а не встроенной.Однако, это почти тривиально, когда try является функцией, которая принимает два аргумента: закрытие в первом аргументе и функция, которая принимает закрытие во втором.

Perl 5 не имеетесть встроенный карри, хотя для этого есть модуль.Однако в Perl 6 встроены карри и первоклассные продолжения, а также многое другое.

2 голосов
/ 27 апреля 2011

Забавно, если не особенно практично, это Церковные цифры . Это способ представления целых чисел, используя только функции. Сумасшедший, я знаю. Вот реализация в JavaScript , которую я сделал. Это может быть проще для понимания, чем реализация Lisp / Haskell. (Но, возможно, нет, если честно. JavaScript не был предназначен для такого рода вещей.)

...