一般的方法是创建一个函数,递归地计算字符串的头部,直到找到错误值或到达结尾。
要做到这一点,你需要
- 了解递归(先决条件:了解递归)以及如何在 Haskell 中编写递归函数
- 知道如何使用head函数
- 很可能知道如何在 Haskell 中使用列表推导
我有notes on Haskell,您可能会觉得它有用,但您可能会发现Yet Another Haskell Tutorial 更全面(3.3 列表;3.5 函数;和 7.8 更多列表 可能是解决我提到的要点的好起点)
EDIT0:
使用守卫测试头元素并仅在它与第二个元素相同时继续的示例:
someFun :: String -> String
someFun[] = []
someFun [x:y:xs]
| x == y = someFun(y:xs)
| otherwise = []
EDIT1:
我有点想说 x = (newlist) 然后而不是 else = [] 有 else = [newlist] 如果这有意义吗?
它在命令式编程范式(例如 C 或 Java)中是有意义的,而对于函数式方法则不那么有意义
这是一个具体的例子,希望能突出引用所暗示的 if,then,else 概念与 SomeFun 函数中发生的情况之间的区别:
当我们调用SomeFun [a,a,b,b] 时,我们将其与SomeFun [x:y:xs] 匹配,因为x 是'a',y 是'a',x==y,然后SomeFun [a,a,b,b] = SomeFun [a,b,b],它再次匹配@987654331 @ 但条件 x==y 为假,所以我们使用 else 守卫,所以我们得到 SomeFun [a,a,b,b] = SomeFun [a,b,b] = []。因此,SomeFun [a,a,b,b] 的结果是[]。
那么数据去哪儿了? .好吧,我会举手承认代码中的一个错误,现在我用它来解释 Haskell 函数的工作原理。
我发现更多地从构造数学表达式而不是编程操作的角度思考是有帮助的。因此,= 右侧的表达式是您的结果,不是命令式的赋值(例如 Java 或 C 意义上的)。
我希望具体的例子已经表明 Haskell 使用替换来评估表达式,所以如果你不想在结果中包含某些东西,那么不要将它包含在那个表达式中。相反,如果您确实想要结果中的某些内容,则将其放入表达式中。
因为你的伪代码是
while x == 'next char in string' 放入要返回的新列表
我将修改 SomeFun 函数来做相反的事情,让你弄清楚需要如何修改它才能按你的意愿工作。
someFun2 :: String -> String
someFun2[] = []
someFun2 [x:y:xs]
| x == y = []
| otherwise = x : someFun(y:xs)
示例输出:
SomeFun2 [a,a,b,b] = []
SomeFun2 [a,b,b,a,b] = [a]
SomeFun2 [a,b,a,b,b,a,b] = [a,b,a]
SomeFun2 [a,b,a,b] = [a,b,a,b]
(此时我想补充一点,这些不同的代码 sn-ps 没有经过测试,因为我手头没有编译器,所以请指出任何错误,以便我修复它们,谢谢)