About your three new features.
sumup' ab | highestNumber a == True = a+b | otherwise = sumup' (above a) (a+b) sumup = sumup' lowestNumber 0
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
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
so this seems like a mistake.