Point-free风格多变量函数组合实现中GHC类型匹配报错求解
报错原因
函数组合运算符.的作用是将单参数函数链式调用,规则为(f . g) arg = f (g arg)。你当前的写法(uncurry (+)) . x展开后等价于\f1 -> uncurry (+) (x f1),这里存在明确的类型不匹配问题:
x f1的类型是(x2 -> y2) -> x1 -> x2 -> (y1, y2),是还需要接收3个参数的柯里化函数- 而
uncurry (+)要求输入参数是Num a => (a,a)类型的二元组,二者类型完全不匹配,因此编译器触发类型错误。
解决方案
你需要调整组合逻辑:先让笛卡尔积函数x完整接收两个函数参数f1、f2,得到类型为a -> a -> (a,a)的二元函数后,再对该函数的返回值应用uncurry (+)求和。
两种可直接运行的实现:
- 显式参数实现(可读性最高)
(<+>) :: Num a => (a -> a) -> (a -> a) -> (a -> a -> a) f1 <+> f2 = \x1 x2 -> uncurry (+) $ x f1 f2 x1 x2
- 组合子实现
利用(->) r的Functor实例,对二元函数的返回值做映射需要两次fmap,配合二元函数组合子(.:) = (.) . (.)即可实现:
(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d (.:) = (.) . (.) (<+>) :: Num a => (a -> a) -> (a -> a) -> (a -> a -> a) (<+>) = (fmap . fmap) (uncurry (+)) .: x
Point-free实现可行性
完全可行,上述第二种实现就是标准的Point-free风格,不需要显式声明任何参数。如果不想额外定义(.:)组合子,也可以直接展开写:
(<+>) = (.) ((fmap . fmap) (uncurry (+))) . x
内容的提问来源于stack exchange,提问作者heinwol
相关产品推荐
相关产品推荐

