函数 g = (.).(.) 的类型是什么?

What is the type of the function g = (.).(.)?

答案是:(a -> b) -> (c -> d -> a) -> c -> d -> b

但是我不知道怎么去。

(.) 具有类型 (b -> c) -> ((a -> b) -> (a -> c))。为了清楚起见,我特意添加了一些括号。在表达式 (.) . (.) 中有三个 (.) 的实例,因此使用不同字母的三个版本的类型会很方便。

  • (.) :: (b -> c) -> ((a -> b) -> (a -> c))(.) 的第一个实例:(.).(.)

  • (.) :: (e -> f) -> ((d -> e) -> (d -> f))(.) 的第二个实例:(.). (.)

  • (.) :: (h -> i) -> ((g -> h) -> (g -> i))(.) 的第三个实例:(.) .(.)

(.) . (.) 等价于 ((.) (.)) (.),它将 (.) 应用到 (.),然后将第一个应用的结果应用到 (.)

申请一审到二审

将参数类型 ((e -> f) -> ((d -> e) -> (d -> f))) 与 (.) (b -> c) 的输入类型相匹配:

b = (e -> f)
c = ((d -> e) -> (d -> f))

然后将 (.) ((a -> b) -> (a -> c)) 的结果类型中的类型变量替换为来自参数的匹配项:

(.) (.) :: (a -> (e -> f)) -> (a -> ((d -> e) -> (d -> f)))

将第一次申请的结果应用于第三次

将参数类型 ((h -> i) -> ((g -> h) -> (g -> i))) 与 (.) (.) (a -> (e -> f)) 的输入类型相匹配:

a = (h -> i)
e = (g -> h)
f = (g -> i)

然后将 (.) (.) (a -> ((d -> e) -> (d -> f))) 的结果类型中的类型变量替换为来自参数的匹配项:

(.) (.) (.) :: (h -> i) -> ((d -> (g -> h)) -> (d -> (g -> i)))

这与您在问题中的类型相同,只是括号更多,字母不同。如果我删除不必要的括号,结果如下:

(.) (.) (.) :: (h -> i) -> (d -> g -> h) -> d -> g -> i

它有什么作用?它接受两个 dg 类型的参数,对它们应用 d -> g -> h 类型的函数,然后对结果应用 h -> i 类型的函数。

类型(.) :: (b->c) -> (a->b) -> (a->c)表示

    g :: a -> b
f     ::      d -> c
--------------------    d ~ b
f . g :: a ->      c

因此

      (.) :: (b->c) -> ((a->b) -> (a->c))
(.)       ::           (   s   ->    r  ) -> (t->s) -> (t->r)
-------------------------------------------------------------
(.) . (.) :: (b->c) ->                       (t->s) -> (t->r)
          ~  (b->c) ->                    (t->a->b) ->  t->a->c 

这是有道理的,因为

  ((.) . (.))   f                            g          x  y =
 = (.) ((.) f) g x y
 =    ((f .) . g) x y = (f .) (g x) y 
                      = (f . g x) y    = f ( g          x  y )

因为 (.) f g x = (f .) g x = (f . g) x = f (g x)(还有 = (. g) f x)。

(f .) 称为 运算符部分 (使用 (.) 运算符)。这是写 (.) f.

的便捷快捷方式