takeEveryNth :: [Int] -> Int -> [Int]
takeEveryNth g destination
| [] destination == []
| otherwise = [g !! destination] ++ takeEveryNth (drop (destination+1) g) destination
我在此代码第4行的标题中始终收到错误消息(|否则=…) 我已经尝试过更改缩进,但无法弄清楚为什么会出现此错误
答案 0 :(得分:2)
之所以不起作用,是因为您的第一个警卫表达式不会求值后跟=
的布尔表达式。
我认为应该这样做:
takeEveryNth :: [Int] -> Int -> [Int]
takeEveryNth g destination
| length g <= destination = []
| otherwise = [g !! destination] ++ takeEveryNth (drop (destination+1) g) destination
测试:
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 = []