Point-free style and using $

前端 未结 5 1686
生来不讨喜
生来不讨喜 2021-01-11 19:10

How does one combine using $ and point-free style?

A clear example is the following utility function:

times :: Int -> [a] -> [a]
t         


        
5条回答
  •  有刺的猬
    2021-01-11 20:12

    In Haskell, function composition is associative¹:

    f . g . h == (f . g) . h == f . (g . h)
    

    Any infix operator is just a good ol' function:

    2 + 3 == (+) 2 3
    f 2 3 = 2 `f` 3
    

    A composition operator is just a binary function too, a higher-order one, it accepts 2 functions and returns a function:

    (.) :: (b -> c) -> (a -> b) -> (a -> c)
    

    Therefore any composition operator can be rewritten as such:

    f . g == (.) f g
    f . g . h == (f . g) . h == ((.) f g) . h == (.) ((.) f g) h
    f . g . h == f . (g . h) == f . ((.) g h) == (.) f ((.) g h)
    

    Every function in Haskell can be partially applied due to currying by default. Infix operators can be partially applied in a very concise way, using sections:

    (-) == (\x y -> x - y)
    (2-) == (-) 2 == (\y -> 2 - y)
    (-2) == flip (-) 2 == (\x -> (-) x 2) == (\x -> x - 2)
    (2-) 3 == -1
    (-2) 3 == 1
    

    As composition operator is just an ordinary binary function, you can use it in sections too:

    f . g == (.) f g == (f.) g == (.g) f
    

    Another interesting binary operator is $, which is just function application:

    f x == f $ x
    f x y z == (((f x) y) z) == f x y z
    f(g(h x)) == f $ g $ h $ x == f . g . h $ x == (f . g . h) x
    

    With this knowledge, how do I transform concat $ replicate n xs into point-free style?

    times n xs = concat $ replicate n xs
    times n xs = concat $ (replicate n) xs
    times n xs = concat $ replicate n $ xs
    times n xs = concat . replicate n $ xs
    times n    = concat . replicate n
    times n    = (.) concat (replicate n)
    times n    = (concat.) (replicate n) -- concat is 1st arg to (.)
    times n    = (concat.) $ replicate n
    times n    = (concat.) . replicate $ n
    times      = (concat.) . replicate
    

    ¹Haskell is based on category theory. A category in category theory consists of 3 things: some objects, some morphisms, and a notion of composition of morphisms. Every morphism connects a source object with a target object, one-way. Category theory requires composition of morphisms to be associative. A category that is used in Haskell is called Hask, whose objects are types and whose morphisms are functions. A function f :: Int -> String is a morphism that connects object Int to object String. Therefore category theory requires Haskell's function compositions to be associative.

提交回复
热议问题