【问题标题】:Why am I getting a parse error on input `|'为什么我在输入“|”时收到解析错误
【发布时间】:2020-06-12 15:20:43
【问题描述】:
takeEveryNth :: [Int] -> Int -> [Int]
takeEveryNth g destination
   | [] destination == []
   | otherwise = [g !! destination] ++ takeEveryNth (drop (destination+1) g) destination

我不断收到此代码第 4 行标题中的错误消息(| 否则 =...) 我已尝试更改缩进,但不知道为什么会出现此错误

【问题讨论】:

  • [] destination 毫无意义。此外,它是... = ...,而不是... == ...

标签: haskell


【解决方案1】:

它不起作用的原因是因为您的第一个保护表达式没有计算为 = 后面的布尔表达式。

我认为应该这样做:

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]

【讨论】:

  • 非常感谢。知道为什么我首先会收到错误吗?
  • 我相信守卫表达式应该评估为布尔值,所以你的第一个守卫不合适
【解决方案2】:

这不起作用的原因是因为解析器需要一个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 -&gt; [a] -&gt; [a]。您可以使用drop :: Int -&gt; [a] -&gt; [a] 在给定元素处安全地拆分,然后执行模式匹配,例如在该结果的模式保护中:

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

【讨论】:

  • 我还在从一本书中学习 Haskell,它没有讨论模式守卫,所以谢谢你教我一些新东西!
猜你喜欢
  • 1970-01-01
  • 2013-06-04
  • 2022-06-11
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 2016-11-15
  • 1970-01-01
  • 2014-01-22
相关资源
最近更新 更多