Haskell recursion implementation without input variable

So, I'm still very new to programming, and I am very struggling with the Haskell syntax. I know what I want to implement, but I'm not sure how to do it, so I came here to ask.

So, I have a bunch of numbers without any special order, which are determined by three different functions. An example of this might be:

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" 

Now for one I want to write a function that checks whether a certain number is this heap, and another function "sum" = "that sums all the elements of a list without an input variable. First I solved these problems by specifying a list and using listcommands to summarize totals and see if there is something " elem " of this list, but I have to solve it without using lists.

So, I have ideas on how to solve this, but I have no idea how to actually write it without getting countless errors. Some examples of what I tried for the validation function:

 check x = if above x /= error "Not part of the stack" || lowestnumber == x then True else False 

I also tried checking with "_", but that didn't work either:

 check x if above x == _ || lowestnumber == x then True else False 

My idea for the sum function was this:

 sum' = lowestnumber + above lowestnumber + above (above lowestnumber) + above (above (above lowestnumber)) 

as well as something like

 sum' = lowestnumber + (above sum') 

What do I understand woul

etc., but I didn't understand how to implement this using recursion, which is apparently the way to go.

Well, hope this question is not too stupid! Hope you can help me :)

Edit: Ok, so these are solutions to my 3 problem functions

 sumup' ab |highestNumber a == True = a+b |otherwise = sumup' (above a) (a+b) sumup = sumup' lowestNumber 0 check' ab |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' xy | 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 
+4
source share
5 answers

If you want to do this without lists, save the total and use recursion.

If you are in the highestnumber , just add this to your current amount and stop, otherwise add the number to your total + n and go to the next above n :

 add n total |highestnumber n = total + n |otherwise = add (above n) (total + n) 

Then you can do

 answer = add lowestnumber 0 
+6
source

You should do this without lists, well, which is sad, because it will be a very idiomatic decision.

The closest idiom will be something in common that can cross your heap. You basically want to reset numbers:

 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 

Once you get this, you can use it to determine the amount, item, etc. as defined in the lists :

 sumPile :: Int sumPile = foldlMyPile (+) 0 elemPile :: Int -> Bool elemPile n = foldlMyPile $ \alreadyFound n' -> alreadyFound || n==n' 
+6
source

Various higher-order functions in Haskell capture various recursive (and corecursion † ) patterns, such as iterate , foldr , unfoldr , etc.

Here we can use until :: (a -> Bool) -> (a -> a) -> a -> a , where until pfx gives the result of iteratively applying f to p , starting from x :

 sumPile = snd $ until (highestnumber . fst) (\(a,b)->(above a, b + above a)) (lowestnumber, lowestnumber) 

also,

 inThePile p = p==until (\n-> highestnumber n || n==p) above lowestnumber 

† basically, recursion with the accumulator, plotting its result on the way forward from the starting case, while regular recursion builds its result on the way back from the base case.

+3
source

About your three new features.

 sumup' ab | highestNumber a == True = a+b | otherwise = sumup' (above a) (a+b) sumup = sumup' lowestNumber 0 -- sum up all numbers in the pile 

it is almost the same as in AndrewC'c answer. this is good, except that == Temp completely superfluous, not needed. sumup' also usually done by an internal function moved to the where clause. Therefore, he should not have a descriptive name. Some use a (schema-inspired?) loop , some go (since do is a reserved syntax keyword). I personally recently started using only g :

 sumup = g lowestNumber 0 -- sum up all numbers in the pile where gn tot -- short, descriptive/suggestive var names | highestNumber n = n + tot | otherwise = g (above n) (n + tot) 

 check b = check' lowestNumber b -- don't need any parens here check' ab |a == b = True |True == highestNumber a && a==b = True -- `True ==` not needed |True == highestNumber a && a/=b = False -- `True ==` not needed |check' (above a) (b) == True = True -- `== True` not needed |otherwise = False 

This is usually written as

 check' ab = (a == b) || (highestNumber a && a==b) || ( not (highestNumber a && a/=b) && check' (above a) b ) 

in the second test, if a==b were true, it already worked in the 1st rule, so we can assume that a/=b now on. therefore, the second test is always false; and get

 check' ab = (a == b) || (not (highestNumber a) && check' (above a) b) 

which looks pretty good. It can also be recorded again with protection, as

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

or, using short suggestive variable names, and with a changed order of arguments, for consistency,

 check' ni | highestNumber i = i == n | otherwise = i == n || check' n (above i) 

which is pretty similar to how the first sumup code is sumup .


Now, the third function. First of all, it is easy to define it in terms of check' too, only starting from a given low number, and not from the bottom:

 higher top low = check low && not (highestNumber low) && check' top (above low) 

("higher" is a more peculiar name, right?). Your version:

 higher :: Integer -> Integer -> Bool higher xy | check x == False = False -- not(check x == False) -- == | check y == False = False -- check x == True -- == | highestNumber y == True = False -- check x | highestNumber x == True = True | x==y = True | higher x (above y) == True = True | otherwise = False 

again, simplifying

 higher xy = check x && check y && not (highestNumber y) && ( highestNumber x || x==y -- really? || higher x (above y) ) -- too strong 

so this seems like a mistake.

+3
source

At first I solved these problems by specifying a list and using listcommands to summarize and see if something is an β€œelement” of this but I have to solve it without using lists.

You can solve this by extending elem, for example:

 x `elem` [1,2,3] 

coincides with

 x == 1 || x == 2 || x == 3 

And while you are on it

 sum' = 4 + 11 + 18 + 2 + 4 + 5 

You can also create a list of all of your items with something like

 elements = takeUntil highestnumber (iterate above lowestnumber) takeUntil p xs = foldr (\xr -> if px then [x] else x:r) [] xs 

This is the only way to see that you can write your verification functions and sums without using constants.


we cannot use takeWhile (not . highestnumber) because we will skip the largest number. Thus, takeUntil must be defined in such a way as to include a takeUntil in its output.

+2
source

All Articles