cube = x*x*x
cube xs = map cube [x | x <-xs]
where x mod 2 == 1
所以我想获取列表的奇数
谢谢大家的帮助!
答案 0 :(得分:4)
上面的代码片段包含一些错误:
where
作为过滤器,但是在Haskell中,where子句用于定义局部范围的变量; (x:xs)
模式,因此即使此模式有效,也会在空白列表上显示错误; [x | x <- xs]
只是列表的标识函数,因此我们可以忽略这一点,此外,不建议将变量命名为与“外部”变量相同,因为这会创建混乱;和x mod 2 == 1
可以替换为odd :: Integral i => i -> Bool
。我们可以通过以下方式解决此问题:
cubeOdds2 :: Integral i => [i] -> [i]
cubeOdds2 = map cube . filter odd
where cube x = x * x * x
例如:
Prelude> cubeOdds2 [1,4,2,5]
[1,125]
因此,我们在这里使用filter :: (a -> Bool) -> [a] -> [a]
来过滤列表,从而仅保留奇数,然后使用map :: (a -> b) -> [a] -> [b]
对这些元素进行映射,并以cube
作为函数接受一个元素并返回该元素的映射。
答案 1 :(得分:2)
您有一些问题。一种是语法错误,另一种是误解了where子句的含义。然后有不必要的模式匹配。最后,不是严格的问题,而是列表符号和高阶函数的组合。
不是条款
where
子句用于变量绑定,例如:
where functionName param1 param2 = <some expression>
该子句对于约束变量无用。对于列表符号样式约束,只需添加逗号和约束:
[x | x <- list, predicate1 x, predicate2 x]
模式匹配
函数cubeOdds2 (x:xs)
将x
绑定到列表中的第一个元素,然后将xs
绑定到其余列表。它也会失败,并且在空列表上会出现异常。
您似乎想要的只是对列表进行操作,因此不要进行模式匹配,而只需使用诸如cubeOdds2 xs
之类的变量名即可。
列表理解符号与高阶函数
列表理解是类似于[a | val <- list, predicate val, let a = someFunction val]
的语法。高阶函数可以完成列表解析所执行的所有操作,例如map
进行someFunction计算并基于谓词进行filter
处理。
某些解决方案
通过这些更改,我们为您的cubeOdds函数提供了三种最终形式。
首先,您要混合使用约定:
cubeOdds3 xs = map cube [x | x <- xs, x `mod` 2 == 1]
第二,仅列出理解:
cubeOdds4 xs = [cube x | x <- xs, x `mod` 2 == 1]
第三,只是高阶函数:
cubeOdds5 xs = map cube (filter (\x -> x `mod` 2 == 1) xs)
代码高尔夫
我们甚至可以进一步使用内置的odd
函数:
cubeOdds6 xs = [cube x | x <- xs, odd x]
也可以使用无点样式:
cubeOdds7 = map cube . filter odd