Haskell中zip与zipWith组合使用报错问题咨询
问题分析:
zipWith zip 报错的原因 先明确几个关键函数的类型签名:
zip :: [a] -> [b] -> [(a,b)]:接受两个列表,返回对应元素组成的元组列表。zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]:接受一个二元函数,以及两个列表,将函数依次作用于两个列表的对应元素,生成结果列表。
你写zipWith zip [1,2,3] [4,5,6]时,错误的核心是类型不匹配:
zipWith要求第一个参数是a -> b -> c类型的二元函数,但zip本身的类型是[x] -> [y] -> [(x,y)]——它需要的是两个列表作为输入,而不是单个元素。
当你运行这段代码时,zipWith会尝试把zip应用到两个输入列表的单个元素上:比如拿1(来自第一个列表)和4(来自第二个列表)传给zip。但1是Num类型,不是列表,编译器为了满足zip的类型要求,会试图把数字推断成列表类型,这就导致了No instance for (Num [()])的错误——它找不到Num类型实例可以把数字转换成[()]这种列表类型。
用zipWith实现zip效果的正确方式
如果想用zipWith得到和zip一样的结果,应该用元组构造函数(,),它的类型是a -> b -> (a,b),完全符合zipWith对第一个参数的要求:
zipWith (,) [1,2,3] [4,5,6] -- 结果:[(1,4),(2,5),(3,6)]
本质上,zip就是zipWith (,)的语法糖,两者行为完全一致。
内容的提问来源于stack exchange,提问作者kesarling
相关产品推荐
相关产品推荐

