我对Haskell来说真的很新,我需要返回一个"已经修改过"输入的功能。
我猜你不能复制和修改原始函数(基于某些条件),所以你必须直接实现自己的行为,然后调用原始函数?
这是我的方法:
switchFirstEgg eggCarton = if eggCarton 1 == 0
then switchedCarton where switchedCarton position = if position == 1 then 2 else eggCarton position
else if eggCarton 1 == 1
then switchedCarton where switchedCarton position = if position == 1 then 0 else eggCarton position
else if eggCarton 1 == 2
then switchedCarton where switchedCarton position = if position == 1 then 1 else eggCarton position
else switchedCarton where switchedCarton position = eggCarton position
我从GHCI得到的错误是
haskell / eggcartons.hs:42:54:解析输入'where'的错误
指向第一个where
之后的第一个单词。
(供参考:我还尝试在http://pastebin.com/2wTqAqpm设置更多括号,我尝试使用警卫http://pastebin.com/RVm28Y7n进行操作,但这只是在没有深入理解的情况下使情况变得更糟?至少警卫在这里为我工作http://pastebin.com/uQeFwLU5)
我在Haskell中搜索了返回的函数,但是我只得到了一些我用where
事件的随机信息。
我的观念是对的吗?这只是一个小错误吗?
对于有关返回函数语法的进一步阅读的任何帮助也非常感谢!
答案 0 :(得分:6)
首先让我们稍微阅读......
switchFirstEgg ec
= if ec 1 == 0
then sc where sc pos = if pos == 1
then 2
else ec pos
else if ec 1 == 1
then sc where sc pos = if pos == 1
then 0
else ec pos
else if ec 1 == 2
then sc where sc pos = if position == 1
then 1
else ec pos
else sc where sc pos = ec pos
现在。 where
每个定义只能使用一次,即在您撰写switchFirstEgg _ = ...
之后,您可以关注where
,该=
对sc
之后的所有内容有效。或者,您可以在if
的其中一个定义之后更多地在本地使用。但是你不能把它放在代码中间的任何地方,比如在let
分支中。
非常相似的switchFirstEgg ec
= if ec 1 == 0
then let sc pos = if pos == 1 then 2
else ec pos
in sc
else if ec 1 == 1
then let sc pos = if pos == 1 then 0
else ec pos
in sc
else if ec 1 == 2
then let sc pos = if pos == 1 then 1
else ec pos
in sc
else let sc pos = ec pos
in sc
结构允许这样做,所以你尝试的最简单的翻译是
sc
但那很笨重。如果仅在定义后立即使用一次,您就不需要使用名称定义switchFirstEgg ec
= if ec 1 == 0
then \pos -> if pos == 1 then 2
else ec pos
else if ec 1 == 1
then \pos -> if pos == 1 then 0
else ec pos
else if ec 1 == 2
then \pos -> if pos == 1 then 1
else ec pos
else \pos -> ec pos
。这是一个明确的lambda应用程序:
if
更好,但case
的这一链显然更好地表达为switchFirstEgg ec = case ec 1 of
0 -> \pos -> if pos == 1 then 2
else ec pos
1 -> \pos -> if pos == 1 then 0
else ec pos
2 -> \pos -> if pos == 1 then 1
else ec pos
_ -> \pos -> ec pos
个子句的单个集合。
pos
此时很明显switchFirstEgg ec pos = case ec 1 of
0 -> if pos == 1 then 2
else ec pos
1 -> if pos == 1 then 0
else ec pos
2 -> if pos == 1 then 1
else ec pos
_ -> ec pos
绑定非常统一,所以我们可以将它们全部向上移动:
if
我们在模式匹配后立即switchFirstEgg ec pos = case ec 1 of
0 | pos == 1 -> 2
1 | pos == 1 -> 0
2 | pos == 1 -> 1
_ -> ec pos
。现在这非常适合警卫:
pos
或者,您可以在考虑ec 1
之前立即在switchFirstEgg ec 1 = case ec 1 of
0 -> 2
1 -> 0
2 -> 1
n -> n
switchFirstEgg ec pos = ec pos
上进行匹配:
{{1}}
答案 1 :(得分:3)
看看这是否符合您的要求:
switchFirstEgg eggCarton =
switchedCarton
where switchedCarton = case (eggCarton 1) of
0 -> \position -> if position == 1
then 2
else eggCarton position
1 -> \position -> if position == 1
then 0
else eggCarton position
2 -> \position -> if position == 1
then 1
else eggCarton position
_ -> \position -> eggCarton position
在函数定义中只能有一个where
子句(尽管where
子句中的函数定义可以有自己的where子句。)