在没有输入变量的情况下在Haskell中实现递归

use*_*050 4 recursion haskell

因此我对编程仍然很新,而且我在使用Haskell的语法时遇到了很多困难.我知道我想要实现什么,但我不确定该怎么做,所以我来这里问.

所以我所拥有的是由"3个不同的函数"定义的没有特定顺序的"堆积"数字.一个例子是:

lowestnumber = 4
highestnumber 5 = True
highestnumber _ = False
above 4 = 11
above 11 = 18
above 18 = 2
above 2  = 3
above 3  = 5
above 5  = error "highest Number"
above _ = error "Not part of the pile"
Run Code Online (Sandbox Code Playgroud)

现在,我想编写一个函数来检查某个数字是否是这一堆的一部分,另一个函数"sum'=",它总结了列表中没有输入变量的所有元素.首先,我通过定义一个列表并使用list命令来解决这些问题,以便总结并查看elem该列表中是否有某些东西,但我应该在不使用列表的情况下解决它.

所以我有如何解决这个问题的想法,但我不知道如何在没有收到无数错误的情况下实际编写它.我尝试过检查功能的一些例子:

check x = if above x /= error "Not part of the stack" || lowestnumber == x then True else False
Run Code Online (Sandbox Code Playgroud)

我也尝试过这样的"_"检查,但它也不起作用:

check x if above x == _ || lowestnumber == x then True else False
Run Code Online (Sandbox Code Playgroud)

我对sum函数的想法是这样的:

sum' = lowestnumber + above lowestnumber + above (above lowestnumber) + above (above (above lowestnumber))
Run Code Online (Sandbox Code Playgroud)

或者类似的东西

sum' = lowestnumber + (above sum') 
Run Code Online (Sandbox Code Playgroud)

我明白了

等等,但我没有想出如何使用递归实现这一点,这显然是要走的路.

希望这个问题太愚蠢了!我希望你能帮帮我 :)

编辑:好的,所以这些是我的3个功能问题的解决方案

sumup' a b 
           |highestNumber a == True = a+b 
           |otherwise = sumup' (above a) (a+b)

sumup = sumup' lowestNumber 0



check' a b 
            |a == b = True
            |True == highestNumber a && a==b = True
            |True == highestNumber a && a/=b = False
            |check' (above a) (b) == True = True
            |otherwise = False

check b = check' (lowestNumber) (b)



above' :: Integer -> Integer -> Bool
above' x y
            | check x == False = False
            | check y == False = False
            | highestNumber y == True = False
            | highestNumber x == True = True
            | x==y = True
            | above' x (above y) == True = True
            | otherwise = False
Run Code Online (Sandbox Code Playgroud)

lef*_*out 6

应该在没有名单的情况下这样做,这很难过,因为这将是非常惯用的解决方案.

最后一个惯用的是通用的,能够穿过那里的桩.你基本上想要折叠数字:

foldlMyPile :: (a -> Int -> a) -> a -> {- Pile -> -} a
foldlMyPile f = go lowestNumber
 where go n accum
         | highestNumber n  = result
         | otherwise        = go (above n) result
        where result = f accum n
Run Code Online (Sandbox Code Playgroud)

一旦你有了这个,你就可以用它来定义sum,element等,就像它们在列表中定义一样:

sumPile :: Int
sumPile = foldlMyPile (+) 0

elemPile :: Int -> Bool
elemPile n = foldlMyPile $ \alreadyFound n' -> alreadyFound || n==n'
Run Code Online (Sandbox Code Playgroud)


And*_*ewC 6

如果要在没有列表的情况下执行此操作,请保持运行总计,并使用递归.

如果你在highestnumber,只需将其添加到当前总数并停止,否则,将数字添加到总数中total + n并继续下一个above n:

add n total |highestnumber n = total + n
            |otherwise = add (above n) (total + n)
Run Code Online (Sandbox Code Playgroud)

那你可以做

answer = add lowestnumber 0
Run Code Online (Sandbox Code Playgroud)

  • @ user2299050:你也可以把你的解决方案写成答案! (3认同)