What are some interesting uses of higher-order functions?

后端 未结 14 567
走了就别回头了
走了就别回头了 2021-01-30 00:55

I\'m currently doing a Functional Programming course and I\'m quite amused by the concept of higher-order functions and functions as first class citizens. However, I can\'t yet

相关标签:
14条回答
  • 2021-01-30 01:52

    Here's a small paraphrased code snippet:

    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
    

    This uses several "higher order" functions:

    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
    

    (.) is the . operator, and (>>=) is the do-notation "line break operator".

    When programming in Haskell you just use them. Where you don't have the higher order functions is when you realize just how incredibly useful they were.

    0 讨论(0)
  • 2021-01-30 01:56

    Many techniques used in OO programming are workarounds for the lack of higher order functions.

    This includes a number of the design patterns that are ubiquitous in functional programming. For example, the visitor pattern is a rather complicated way to implement a fold. The workaround is to create a class with methods and pass in an element of the class in as an argument, as a substitute for passing in a function.

    The strategy pattern is another example of a scheme that often passes objects as arguments as a substitute for what is actually intended, functions.

    Similarly dependency injection often involves some clunky scheme to pass a proxy for functions when it would often be better to simply pass in the functions directly as arguments.

    So my answer would be that higher-order functions are often used to perform the same kinds of tasks that OO programmers perform, but directly, and with a lot less boilerplate.

    0 讨论(0)
提交回复
热议问题