如何找到(\ x y z-> x。y z)的类型

时间:2018-07-31 08:42:22

标签: haskell types

我正在尝试找到(\x y z -> x . y z)的类型,但是没有找到与ghci相同的类型

(\x y z -> x . y z) :: (b -> c) -> (t -> a -> b) -> t -> a -> c

在删除中缀函数并获得(\x y z -> (.) x (y z))之后,我不确定如何继续。

2 个答案:

答案 0 :(得分:5)

向后工作,并分配类型变量,直到指定它们为止:

-- We assign types one by one:
(.) x (y z) :: a -- So,
(y z) :: b
(.) x :: b -> a
x :: c
(.) :: c -> b -> a

但是我们知道(.) :: (y -> z) -> (x -> y) -> (x -> z),所以,我们可以用~来写一些类型:

c ~ y -> z
b ~ x -> y
a ~ x -> z

我们现在知道:

x :: y -> z
(.) x (y z) :: x -> z
y z :: x -> y

所以

z :: d
y :: d -> x -> y

最后,我们只需完成函数的类型

--                     (type of x) (Type of y) (type of z) (return type)
(\x y z -> x . y z) :: (y -> z) -> (d -> x -> y) -> d -> (x -> z)

最后,我们可以要求GHCi进行确认:

Prelude> :t (\x y z -> x . y z)
(\x y z -> x . y z) :: (b -> c) -> (t -> a -> b) -> t -> a -> c

答案 1 :(得分:5)

我们可以如下扩展表达式\x y z -> x . y z

  \x y z   -> x . y z
≡ \x y z w -> x (y z w) -- because (f . g) ≡ (\x -> f (g x))
≡ \f g x y -> f (g x y) -- renaming the variables

现在,我们可以看一下类型:

x :: a1
y :: a2

-- Because g is applied to x and y:

g :: (a1 -> a2 -> b)

-- Because f is applied to (g x y):

f :: (b -> c)

-- Therefore:

(\f g x y -> f (g x y)) :: (b -> c) -> (a1 -> a2 -> b) -> a1 -> a2 -> c
                        -- └──┬───┘    └──────┬──────┘    │     │
                        --    f               g           x     y

如您所见,此函数仅由fg组成:

          ┌───────┐       ┌───────┐
x :: a1 ──┤       │       │       │
          │   g   ├── b ──┤   f   ├── c
y :: a2 ──┤       │       │       │
          └───────┘       └───────┘

有关更多信息,请查看以下问答:What does (f .) . g mean in Haskell?