为什么在输入'|'上出现解析错误

时间:2020-02-28 13:50:01

标签: haskell

takeEveryNth :: [Int] -> Int -> [Int]
takeEveryNth g destination
   | [] destination == []
   | otherwise = [g !! destination] ++ takeEveryNth (drop (destination+1) g) destination

我在此代码第4行的标题中始终收到错误消息(|否则=…) 我已经尝试过更改缩进,但无法弄清楚为什么会出现此错误

2 个答案:

答案 0 :(得分:2)

之所以不起作用,是因为您的第一个警卫表达式不会求值后跟=的布尔表达式。

我认为应该这样做:

takeEveryNth :: [Int] -> Int -> [Int]
takeEveryNth g destination
   | length g <= destination = []
   | otherwise = [g !! destination] ++ takeEveryNth (drop (destination+1) g) destination

Demo

测试:

takeEveryNth [1..10] 2

产生:

[3,6,9]

takeEveryNth [1..10] 1

产生:

[2,4,6,8,10]

答案 1 :(得分:1)

之所以不起作用,是因为解析器期望使用 singe =,而不是警卫队的==。话虽这么说,但您可以将防护当作模式来使用。警卫队使用类型为Bool的表达式。因此,像| [] destination = ...这样的警卫毫无意义。

您可能想要实现以下内容:

takeEveryNth :: [Int] -> Int -> [Int]
takeEveryNth [] _ = []
takeEveryNth g destination = [g !! destination] ++ takeEveryNth (drop (destination+1) g) destination

但这还不够,因为如果列表g包含少于n个元素,则g !! destination将出错。此外,不必将值包装在单例列表中,可以使用“ cons”函数(:) :: a -> [a] -> [a]。您可以使用drop :: Int -> [a] -> [a]安全地分割给定元素,然后执行模式匹配,例如在结果的模式后卫

takeEveryNth :: [Int] -> Int -> [Int]
takeEveryNth g n
    | (x:xs) <- drop (n-1) g = x : takeEveryNth xs n
    | otherwise = []
相关问题