我一直试图理解这段代码,但我无法清楚地把它包起来:
ghci > :t zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
ghci > :t ($)
($) :: (a -> b) -> a -> b
ghci > let c = zipWith ($)
ghci > :t c
c :: [b -> c] -> [b] -> [c]
Run Code Online (Sandbox Code Playgroud)
如何[b -> c]产生上述类型的签名?
为了进行类型检查,zipWith ($)我们必须将zipWith第一个参数的类型统一为类型($).我会把它们一起写出来并用独特的名字来表达它.
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
($) :: ((x -> y) -> x -> y)
Run Code Online (Sandbox Code Playgroud)
因此,zipWithtypechecks当且仅当我们可以假设a ~ (x -> y),b ~ x和c ~ y.没有什么可以阻止这种统一成功,所以我们可以将这些名称替换回类型zipWith.
zipWith :: ((x -> y) -> x -> y) -> [x -> y] -> [x] -> [y]
($) :: ((x -> y) -> x -> y)
Run Code Online (Sandbox Code Playgroud)
然后继续申请,因为现在一切都很好
zipWith ($) :: [x -> y] -> [x] -> [y]
Run Code Online (Sandbox Code Playgroud)
这相当于您所看到的类型的类型变量名的特定选择.