不断在Haskell中获得解析提示错误我在做什么错

时间:2019-02-16 16:18:49

标签: haskell

cube = x*x*x
cube xs = map cube [x | x <-xs] 
           where x mod 2 == 1

所以我想获取列表的奇数

谢谢大家的帮助!

2 个答案:

答案 0 :(得分:4)

上面的代码片段包含一些错误:

  1. 您在这里使用where作为过滤器,但是在Haskell中,where子句用于定义局部范围的变量;
  2. 您仅定义了(x:xs)模式,因此即使此模式有效,也会在空白列表上显示错误;
  3. [x | x <- xs]只是列表的标识函数,因此我们可以忽略这一点,此外,建议将变量命名为与“外部”变量相同,因为这会创建混乱;和
  4. 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