如果那么......之后不止一个函数,在Haskell中不起作用

时间:2013-10-11 18:02:48

标签: haskell if-statement conditional-statements ghc

我有一个基本问题,如果..那么我不能有多个功能,为什么?

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次,而不是更多。

2 个答案:

答案 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

您还可以使用caseMultyIf扩展名

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,如纯IOIORef,如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的第一个参数是一对,而在递归定义中你提供了一个列表。