我有一个基本问题,如果..那么我不能有多个功能,为什么?
check [] _ _ = []
check (x:xs) limit counter = if (x> head xs && counter < limit)
then incr counter -- I want here add another action
else if ( x < head xs )
then check xs limit counter
else incr x
main = do
print $ check [4,3,5,6] 1 0
--- The answer I aim is : [3,4,5,6]
检查的目的是找出每个元素是否大于下一个元素,如果是,则增加计数器并执行另一个操作,例如交换它们的位置,这个操作有一个限制,就像这里只是1次,意味着它只能做1次,而不是更多。
答案 0 :(得分:3)
你可以使用警卫:
check [] _ _ = []
check (x:xs) limit counter
| x> head xs && counter < limit = incr counter
| x < head xs = check xs limit counter
| otherwise = incr x
您还可以使用case
和MultyIf
扩展名
而action
来自incr counter
您可以写check xs limit (counter + 1)
关于交换,你可以尝试
...
| x> head xs && counter < limit = check (head xs : x : tail xs) limit (counter + 1)
我知道,您还需要head [] = error
的特殊情况,因此您应该将功能划分为check (x:y:xs) ..
和check [x]
。
因此,对于check (x:y:xs) ..
,我们可以重写
...
| x> y && counter < limit = check (y : x : xs) limit (counter + 1)
当你这样做时,你已经发现我们有空列表作为结果。 但是你想保存修改后的列表
因此,尝试添加更改检查功能
check' xs = reverse . check ([], xs) 0
check ( modXs, []) _ _ = modXs
check ( modXs, [x]) _ _ = x : modXs
check ( modXs, (x:y:xs)) counter limit = ...
要点
在函数内部没有“静态局部变量”,但在大多数情况下,欢迎递归。
如果真的需要使用“静态局部变量”,你可以使用“内容中的数据”:monad,如纯IO
,IORef
,如State
答案 1 :(得分:1)
关于check
的第二次实施:
check ( modXs, []) _ _ = modXs
check ( modXs, [x]) _ _ = x : modXs
check ( modXs, (x1:x2:xs)) counter limit
| x1 > x2 && counter > limit = x2:check (x1 : xs) (incr counter) limit
| otherwise = x1 : check (x2 : xs) counter limit
你几乎就在那里,但输入不好是因为check
的第一个参数是一对,而在递归定义中你提供了一个列表。