Type of fun g x = ys where ys = [x] ++ filter (curry g x) ys?

前端 未结 2 722
再見小時候
再見小時候 2020-12-07 04:38

I\'m trying to understand why the type of fun g x = ys where ys = [x] ++ filter (curry g x) ys is ((a, a) -> Bool) -> a -> [a].

I

2条回答
  •  一生所求
    2020-12-07 05:23

    We can derive types in Haskell in a more or less mechanical manner, using the general scheme of

    foo      x =  y                              -- is the same as
    foo   = \x -> y                              -- so the types are
    foo   :: a -> b          , x :: a , y :: b   -- so that
    foo      x :: b                              
    

    which means that e.g.

    f    x    y    z :: d    , x :: a , y :: b, z :: c
    

    entails

    f    x    y :: c -> d
    f    x :: b -> c -> d
    f :: a -> b -> c -> d
    

    etc. With these simple tricks type derivation will become trivial for you. Here, with

    filter :: (a -> Bool) -> [a] -> [a]  
    curry  :: ((a, b) -> c) -> a -> b -> c
    (++)   :: [a] -> [a] -> [a]
    

    we simply write down the stuff carefully lined up, processing it in a top-down manner, consistently renaming and substituting the type variables, and recording the type equivalences on the side:

    fun    g    x = ys   where   ys = [x] ++ filter (curry g x) ys 
    fun    g    x :: c              , ys :: c
    fun    g :: b -> c              , x  :: b 
    fun :: a -> b -> c              , g  :: a 
    
    ys = [x] ++ filter (curry g x) ys
    c  ~  c
    
    (++)    [x]     (filter (curry g x) ys) :: c    
    (++) :: [a1] -> [a1]                    -> [a1]   
    -----------------------------------------------
    (++) :: [b]  -> [b]                     -> [b]    , a1 ~ b , c ~ [b]
    
    filter    (curry g x )     ys  :: [b] 
    filter :: (a2 -> Bool) -> [a2] -> [a2]            , a2 ~ b
    --------------------------------------
    filter :: (b  -> Bool) -> [b]  -> [b]
    
    curry     g                   x  :: b -> Bool
    curry :: ((a3, b) -> c3  ) -> a3 -> b -> c3       , c3 ~ Bool , a3 ~ b
    -------------------------------------------
    curry :: ((b , b) -> Bool) -> b  -> b -> Bool     , a ~ ((b,b) -> Bool)

    so we have that a ~ ((b,b) -> Bool) and c ~ [b], and thus

    fun :: a               -> b ->  c
    fun :: ((b,b) -> Bool) -> b -> [b]
    

    which is the same as ((a,a) -> Bool) -> a -> [a], up to a consistent renaming of type variables.

提交回复
热议问题