Point-free style and using $

前端 未结 5 1721
生来不讨喜
生来不讨喜 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条回答
  •  Happy的楠姐
    2021-01-11 19:58

    By extending FUZxxl's answer, we got

    (.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
    (.:) = (.).(.)
    
    (.::) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e
    (.::) = (.).(.:)
    
    (.:::) :: (e -> f) -> (a -> b -> c -> d -> e) -> a -> b -> c -> d -> f
    (.:::) = (.).(.::)
    
    ...
    

    Very nice.

    Bonus

    (.:::) :: (e -> f) -> (a -> b -> c -> d -> e) -> a -> b -> c -> d -> f
    (.:::) = (.:).(.:)
    

    Emm... so maybe we should say

    (.1) = .
    
    (.2) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
    (.2) = (.1).(.1)
    
    (.3) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e
    (.3) = (.1).(.2)
    -- alternatively, (.3) = (.2).(.1)
    
    (.4) :: (e -> f) -> (a -> b -> c -> d -> e) -> a -> b -> c -> d -> f
    (.4) = (.1).(.3)
    -- alternative 1 -- (.4) = (.2).(.2)
    -- alternative 2 -- (.4) = (.3).(.1)
    

    Even better.

    We can also extend this to

    fmap2 :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
    fmap2 f = fmap (fmap f)
    
    fmap4 :: (Functor f, Functor g, Functor h, functro i) 
       => (a -> b) -> f (g (h (i a))) -> f (g (h (i b)))
    fmap4 f = fmap2 (fmap2 f)
    

    which follows the same pattern.

    It would be even better to have the times of applying fmap or (.) parameterized. However, those fmap or (.)s are actually different on type. So the only way to do this would be using compile time calculation, for example TemplateHaskell.

    For everyday uses, I would simply suggest

    Prelude> ((.).(.)) concat replicate 5 [1,2]
    [1,2,1,2,1,2,1,2,1,2]
    Prelude> ((.).(.).(.)) (*10) foldr (+) 3 [2,1]
    60
    

提交回复
热议问题