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)
的重构感到满意吗?这显然是一种无害的局部重写--以如此剧烈的方式改变了行为?(我不是说这些问题无法回答,但仔细思考如何回答可能会有所启发。)可能相关的问题: