为什么zipWith.zip可以工作?

Luk*_*ins 3 haskell zipwith

我正在实现一个combine :: [[a]] -> [[b]] -> (a -> b -> c) -> [[c]]给出两个2D列表的函数,将给定的函数应用于2D列表f :: a -> b -> c的条目.换一种说法:

          [[a, b, c],    [[r, s, t],          [[f a r, f b s, f c t], 
combine    [d, e, g],     [u, v, w],   f   =   [f d u, f e v, f g w],
           [h, i, j]]     [x, y, z]]           [f h x, f i y, f j z]]
Run Code Online (Sandbox Code Playgroud)

现在我怀疑combine = zipWith . zipWith,因为我已经尝试过,它给了我预期的结果,例如

(zipWith . zipWith) (\x y -> x+y) [[1,2,3],[4,5,6]] [[7,8,9],[10,11,12]]
Run Code Online (Sandbox Code Playgroud)

给出了预期的结果[[8,10,12],[14,16,18]],但我不明白为什么这工作,因为我不明白的类型如何zipWith . zipWith原来是(a -> b -> c) -> [[a]] -> [[b]] -> [[c]].

(.)这里仍执行通常的功能组成?如果是这样,你能解释一下这是如何适用的zipWith吗?

tho*_*ron 7

要推断表达式的类型zipWith . zipWith,您可以通过以下方式模拟脑中的统一.

所述第一zipWith有类型(a -> b -> c) -> ([a] -> [b] -> [c]),第二(s -> t -> u) -> ([s] -> [t] -> [u])(.)具有类型(m -> n) -> (o -> m) -> (o -> n).

要进行类型检查,您需要:

  • m = (a -> b -> c)
  • n = ([a] -> [b] -> [c])
  • o = (s -> t -> u)
  • m= ([s] -> [t] -> [u])=> a= [s],b= [t],c= [u]因为第一个约束

然后返回的类型是o -> n其是(s -> t -> u) -> ([a] -> [b] -> [c])从所述约束和去一步(s -> t -> u) -> ([[s]] -> [[t]] -> [[u]]).