haskell函数,用于对列表中的数字进行求和和和乘法

haskell函数,用于对列表中的数字进行求和和和乘法,haskell,Haskell,我试着做一个函数,给定一个操作符,一个函数将通过如下列表: reduce (*) even [1,2,3,4,5] => 8 reduce (+) odd [1,2,3,4,5] => 9 起初我有这样的想法: reduce :: (Int-> Int-> Int) -> (Int->Bool) -> [Int] -> Int reduce op x y = foldl op 1 (filter x y) > reduce Sum ev

我试着做一个函数,给定一个操作符,一个函数将通过如下列表:

reduce (*) even [1,2,3,4,5] => 8
reduce (+) odd [1,2,3,4,5]  => 9
起初我有这样的想法:

reduce :: (Int-> Int-> Int) -> (Int->Bool) -> [Int] -> Int
reduce op x y = foldl op 1 (filter x y)
> reduce Sum even [1..5]
Sum {getSum = 6}
> reduce Product odd [1..5]
Product {getProduct = 15}
它在乘法方面效果很好,但在求和时加了一个数字。因此,我考虑添加一个if:

reduce :: (Int-> Int-> Int) -> (Int->Bool) -> [Int] -> Int
reduce op x y = 
    if op == (*) then foldl op 1 (filter x y)
        else if op == (+) then foldl op 0 (filter x y)
            else 0
但是,当我执行此操作时,会出现以下错误:

定义reduce所需的Eq(Int->Int->Int)实例

这到底是什么意思?有什么想法吗?提前谢谢

这到底是什么意思?有什么想法吗?提前谢谢

您正在尝试将一些
(Int->Int->Int)
与另一个进行比较。但函数不能在相等性上进行检查。请改为提供初始值:

reduce :: (Int -> Int -> Int) -> (Int -> Bool) -> Int -> [Int] -> Int
reduce op f x xs = foldl op x (filter f xs)
顺便说一下,您可以概括函数的类型:

reduce :: (b -> a -> b) -> (a -> Bool) -> b -> [a] -> a
reduce op f x xs = foldl op x (filter f xs)
或者,使用幺半群和
foldMap

这到底是什么意思?有什么想法吗?提前谢谢

您正在尝试将一些
(Int->Int->Int)
与另一个进行比较。但函数不能在相等性上进行检查。请改为提供初始值:

reduce :: (Int -> Int -> Int) -> (Int -> Bool) -> Int -> [Int] -> Int
reduce op f x xs = foldl op x (filter f xs)
顺便说一下,您可以概括函数的类型:

reduce :: (b -> a -> b) -> (a -> Bool) -> b -> [a] -> a
reduce op f x xs = foldl op x (filter f xs)

或者,使用monoid和
foldMap

这意味着,对于当前的导入,您无法比较函数是否相等(即使使用合适的导入,也没有真正好的方法来实现您要求的相等)

一个简单的解决方案是要求用户提供操作和装置,因此:

reduce op u x y = foldl op u (filter x y)
在许多感兴趣的情况下,已经有一个指定运算符和单位的
Monoid
实例。例如,有<代码>和<代码>和<代码>产品< /代码>实例,因此您可以考虑编写

reduce inject p = foldMap inject . filter p
使用的方法如下:

reduce :: (Int-> Int-> Int) -> (Int->Bool) -> [Int] -> Int
reduce op x y = foldl op 1 (filter x y)
> reduce Sum even [1..5]
Sum {getSum = 6}
> reduce Product odd [1..5]
Product {getProduct = 15}

这意味着,对于当前的导入,您无法比较函数是否相等(即使使用合适的导入,也没有真正好的方法来实现您要求的相等)

一个简单的解决方案是要求用户提供操作和装置,因此:

reduce op u x y = foldl op u (filter x y)
在许多感兴趣的情况下,已经有一个指定运算符和单位的
Monoid
实例。例如,有<代码>和<代码>和<代码>产品< /代码>实例,因此您可以考虑编写

reduce inject p = foldMap inject . filter p
使用的方法如下:

reduce :: (Int-> Int-> Int) -> (Int->Bool) -> [Int] -> Int
reduce op x y = foldl op 1 (filter x y)
> reduce Sum even [1..5]
Sum {getSum = 6}
> reduce Product odd [1..5]
Product {getProduct = 15}

让你思考一下:
(\xy->x+y+0)
应该等于
(\xy->x+y)
?如果是这样,您建议用什么算法来确定?如果不是,您真的对将
reduce(\x y->x+y)
更改为
reduce(\x y->x+y+0)
的重构感到满意吗?这显然是一种无害的局部重写--以如此剧烈的方式改变了行为?(我不是说这些问题无法回答,但仔细思考如何回答可能会有所启发。)可能相关的问题:供您思考:
(\x y->x+y+0)
是否应等于
(\x y->x+y)
?如果是这样,您建议用什么算法来确定?如果不是,您真的对将
reduce(\x y->x+y)
更改为
reduce(\x y->x+y+0)
的重构感到满意吗?这显然是一种无害的局部重写--以如此剧烈的方式改变了行为?(我不是说这些问题无法回答,但仔细思考如何回答可能会有所启发。)可能相关的问题: