4

在 GHCI prelude> 中使用 :t 来查找函数的类型:

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

(:) :: a -> [a] -> [a]

((.)(:)) :: (a -> b) -> a -> [b] -> [b]   -- (what happened here?)

我了解单个功能的结果,但部分应用时我不了解。

地图地图的类型是什么?我在此页面上找到了答案,如何以代数方式执行此操作。但是我在((.)(:)).

当你想知道的类型时,方法是((.)(:))什么?有没有一种思维方式可以用于函数的任何部分应用?

提前致谢。

4

2 回答 2

9

The best thing to do, when you want to infer a type for a partial application is to start from the most general types of your building blocks and search for matches between the types you're composing. Let me make this more clear by describing you the reasoning I followed for the type you was searching for.

First of all, let's rename the type variables for (:) in order to avoid confusion:

(.) :: (b -> c) -> (a -> b) -> a -> c
(:) :: d -> [d] -> [d]

(.) (:) partially applies (:) to (.), providing its first argument only. This means that the first argument of (.), that is of type (b -> c), is instantiated to (d -> ([d] -> [d])), with b == d and c == ([d] -> [d]) (remember that -> is right associative).

If you apply this type substitution in the whole thing, you get that the partially applied (.) loses its first argument (it has been fixed as (:)) and results in (a -> d) -> a -> ([d] -> [d]), that is equivalent to (a -> d) -> a -> [d] -> [d] (again, by right-associativity): this is the type expression you got from ghci.

于 2012-04-05T14:39:14.710 回答
6

要扩展@Riccardo 的答案:

  1. 类型签名的对应

    (b  ->       c     )       -- first argument of (.)
    (d  ->  ([d] -> [d])       --   corresponds to type of (:)
    
  2. 替代

    (a -> b) -> a ->      c    -- rest of (.)'s type, minus first argument
    

    (a -> d) -> a -> ([d] -> [d])
    
  3. 右结合性

    (a -> d) -> a -> [d] -> [d]
    
于 2012-04-05T16:14:50.837 回答