我正在尝试派生zipWith . uncurry
zipWith . uncurry = (.) zipWith uncurry
- 连接为函数
(.) :: (b1 -> c1) -> (a1 -> b1) -> a1 -> c1
zipWith :: (a2 -> b2 -> c2) -> [a2] -> [b2] -> [c2]
uncurry :: (a3 -> b3 -> c3) -> (a3, b3) -> c3
b1 ~ (a2 -> b2 -> c2)
c1 ~ [a2] -> [b2] -> [c2]
a1 ~ (a3 -> b3 -> c3)
b1 ~ (a3, b3) -> c3
将a1
替换为(a3 -> b3 -> c3)
,将c1
替换为[a2] -> [b2] -> [c2]
我得到:
(.) zipWith uncurry :: a1 -> c1 ~ (a3 -> b3 -> c3) -> [a2] -> [b2] -> [c2]
如果我查询:t zipWith . uncurry
的GHCi,我会得到:(a -> b1 -> b -> c) -> [(a, b1)] -> [b] -> [c]
我认为关键在于b1 ~ (a2 -> b2 -> c2) ~ (a3, b3) -> c3
,但我没有意识到如何将我的结果与预期相匹配。
任何帮助?
谢谢,
安。
答案 0 :(得分:4)
如果我们从
开始(.) :: (b -> c) -> (a -> b) -> (a -> c)
zipWith :: (x -> y -> z) -> [x] -> [y] -> [z]
uncurry :: (u -> v -> w) -> (u, v) -> w
然后我们将zipWith
的类型与(b -> c)
和uncurry
的类型与(a -> b)
匹配:
b -> c
(x -> y -> z) -> ([x] -> [y] -> [z])
和
a -> b
(u -> v -> w) -> ((u, v) -> w)
然后我们必须将b
条款等同于
b ~ x -> (y -> z)
b ~ (u, v) -> w
所以w ~ (y -> z)
和x ~ (u, v)
。我们目前已确定的表格:
a ~ u -> v -> w
b ~ x -> y -> z
c ~ [x] -> [y] -> [z]
x ~ (u, v)
w ~ y -> z
因此,我们可以将x
和w
替换为:
a ~ u -> v -> (y -> z)
b ~ (u, v) -> y -> z
c -> [(u, v)] -> [y] -> [z]
我们现在可以完成zipWith . uncurry
的类型:
(u -> v -> y -> z) -> ([(u, v)] -> [y] -> [z])
与GHCi的答案一致。
这些技巧只是排列箭头,然后直接替换,直到你不能再减少它为止。