我正在尝试找到(\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))
之后,我不确定如何继续。
答案 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
如您所见,此函数仅由f
和g
组成:
┌───────┐ ┌───────┐
x :: a1 ──┤ │ │ │
│ g ├── b ──┤ f ├── c
y :: a2 ──┤ │ │ │
└───────┘ └───────┘
有关更多信息,请查看以下问答:What does (f .) . g mean in Haskell?