I have this code to work out the sum of squares of integers in the range of m:n
sumsquares :: Integral a=> Int -> Int -> Int -> Int
sumsquares m n middle
| m > n = error "First number cannot be bigger than second number"
|m==n = m*m
|otherwise = m*m + sumsquares (m+1)n
How would i redefine the function sumsquares for this purpose?
If there is more than one number in the range m:n, compute the middle of the range and add the sum of the squares of (m:middle) to sum of the squares (middle+1:n),
otherwise there is only one number in the range m:n, so m = = n, and the solution is just the square of m. (Note that with this approach the recursion combines two half- solutions: each sub-problem is approximately half in size of the overall problem).
In your original function, the class constraint Integral a in the type signature is obsolete (a is not mentioned anywhere else in the signature, is it?). Furthermore, the third parameter of the function (middle) remains unused. Hence, you could have written it as
sumsquares :: Int -> Int -> Int
sumsquares m n
| m > n = error "First number cannot be bigger than second number"
| m == n = m * m
| otherwise = m * m + sumsquares (m + 1) n
Rewriting it to move from a decrease-and-conquer scheme to a strict divide-and-conquer scheme then just involves adapting the recursive case accordingly:
sumsquares :: Int -> Int -> Int
sumsquares m n
| m > n = error "First number cannot be bigger than second number"
| m == n = m * m
| otherwise = let middle = (m + n) `div` 2
in sumsquares m middle + sumsquares (middle + 1) n
The question remains, of course, why you would want to make this change. One reason could be that you are preparing your algorithm to be adapted for parallelisation: then, indeed, divide-and-conquer is often a better fit than decrease-and-conquer.
Related
Good morning everyone!
I'm using the following function as a fitting example of a function that needs to have a simple input and output. In this case it's a function that converts a number from decimal to binary form, as a list of digits no less, just because it is convenient later on.
I chose to write it like this, because even though a number goes in and a list comes out, another structure is needed as an intermediate step, that will hold the digits found so far and hold the quotient of the division, as input for the next step of the loop. I will clean up the necessary mess before outputing anything, though, by selecting the part of the structure that I'm interested in, in this case the second one , and not counters or other stuff, that I'm done with. (As I mentioned this is an example only, and it's not unusual in other cases to initialize the until loop with a triplet like (a,b,c), only to pick one of them at the end, as I see fit, with the help of additional function, like pickXof3.)
So there,
dec2Bin :: Int -> [Int]
dec2Bin num = snd $ until
(\(n,l) -> n <=0) -- test
(\(n,l) -> (fst $ division n, (snd $ division n):l)) -- main function
(num,[]) -- initialization
where division a = divMod a 2
I find it very convenient that Haskell, although lacking traditional for/while loops has a function like until, which reminds me very much of Mathematica's NextWhile, that I'm familiar with.
In the past I would write sth even uglier, like two functions, a "helper" one and a "main" one, like so
dec2BinHelper :: (Int,[Int]) -> (Int,[Int])
dec2BinHelper (n,l)
| n <= 0 = (n,l)
| otherwise = dec2BinHelper (fst $ division n, (snd $ division n):l)
where division a = divMod a 2
-- a function with the sole purpose to act as a front-end to the helper function, initializing its call parameters and picking up its output
dec2Bin :: Int -> [Int]
dec2Bin n = snd $ dec2BinHelper (n,[])
which I think is unnecessarily bloated.
Still, while the use of until allows me to define just one function, I get the feeling that it could be done even simpler/easier to read, perhaps in a way more fitting to functional programming. Is that so? How would you write such a function differently, while keeping the input and output at the absolutely essential values?
I strongly prefer your second solution. I'd start a clean-up with two things: use pattern matching, and use where to hide your helper functions. So:
dec2Bin :: Int -> [Int]
dec2Bin n = snd $ dec2BinHelper (n, []) where
dec2BinHelper (n, l)
| n <= 0 = (n, l)
| otherwise = dec2BinHelper (d, m:l)
where (d, m) = divMod n 2
Now, in the base case, you return a tuple; but then immediately call snd on it. Why not fuse the two?
dec2Bin :: Int -> [Int]
dec2Bin n = dec2BinHelper (n, []) where
dec2BinHelper (n, l)
| n <= 0 = l
| otherwise = dec2BinHelper (d, m:l)
where (d, m) = divMod n 2
There's no obvious reason why you should pass these arguments in a tuple, rather than as separate arguments, which is more idiomatic and saves some allocation/deallocation noise besides.
dec2Bin :: Int -> [Int]
dec2Bin n = dec2BinHelper n [] where
dec2BinHelper n l
| n <= 0 = l
| otherwise = dec2BinHelper d (m:l)
where (d, m) = divMod n 2
You can swap the arguments to dec2BinHelper and eta-reduce; that way, you will not be shadowing the definition of n.
dec2Bin :: Int -> [Int]
dec2Bin = dec2BinHelper [] where
dec2BinHelper l n
| n <= 0 = l
| otherwise = dec2BinHelper (m:l) d
where (d, m) = divMod n 2
Since you know that n > 0 in the recursive call, you can use the slightly faster quotRem in place of divMod. You could also consider using bitwise operations like (.&. 1) and shiftR 1; they may be even better, but you should benchmark to know for sure.
dec2Bin :: Int -> [Int]
dec2Bin = dec2BinHelper [] where
dec2BinHelper l n
| n <= 0 = l
| otherwise = dec2BinHelper (r:l) q
where (q, r) = quotRem n 2
When you don't have a descriptive name for your helper function, it's traditional to name it go or loop.
dec2Bin :: Int -> [Int]
dec2Bin = go [] where
go l n
| n <= 0 = l
| otherwise = go (r:l) q
where (q, r) = quotRem n 2
At this point, the two sides of the conditional are short enough that I'd be tempted to put them on their own line, though this is something of an aesthetic choice.
dec2Bin :: Int -> [Int]
dec2Bin = go [] where
go l n = if n <= 0 then l else go (r:l) q
where (q, r) = quotRem n 2
Finally, a comment on the name: the input isn't really in decimal in any meaningful sense. (Indeed, it's much more physically accurate to think of the input as already being in binary!) Perhaps int2Bin or something like that would be more accurate. Or let the type speak for itself, and just call it toBin.
toBin :: Int -> [Int]
toBin = go [] where
go l n = if n <= 0 then l else go (r:l) q
where (q, r) = quotRem n 2
At this point I'd consider this code quite idiomatic.
The following data structure can be tested with the Tasty-SmallCheck related code that follows. There is a relation that has to hold with the constructor ShB: the second and the third positive integers should be at most as large as the first one.
data Shape = ShA Int Int Bool
| ShB Int Int Int Bool Bool
deriving (Show,Read,Eq)
The constructor ShA should have positive Int's but otherwise there is no relation between the parameters.
auxShA :: (Positive Int, Positive Int, Bool) -> Shape
auxShA (i,j,b) = ShA (fromIntegral i) (fromIntegral j) b
auxShB :: (Positive Int, Positive Int, Positive Int) -> Bool -> Bool -> Shape
auxShB (a1,a2,a3) = ShB i u d
where
(i,u,d) = auxTriplet (a1,a2,a3)
auxTriplet :: (Positive Int, Positive Int, Positive Int) -> (Int,Int,Int)
auxTriplet (a,b,c)
| a >= b && a >= c = (fromIntegral a, fromIntegral b, fromIntegral c)
| b >= a && b >= c = (fromIntegral b, fromIntegral a, fromIntegral c)
| otherwise = (fromIntegral c, fromIntegral a, fromIntegral b)
consB :: (Serial m a1, Serial m a2, Serial m a3, Serial m b, Serial m c) =>
((a1,a2,a3) -> b -> c -> e) -> Series m e
consB f = decDepth $
f <$> series
<~> series
<~> series
instance Monad m => Serial m Shape where
series = cons1 auxShA \/ consB auxShB
The generated cases are otherwise ok but there are duplicates that can be seen e.g. with
list 4 series :: [Shape]
The question is, how to generate the test cases with SmallCheck (tasty) when the following holds?
there are properties that has to hold, e.g. the first parameter has to Positive
what if the first parameter should be larger than 10::Int?
And continuing, what if the second parameter should between the first - 5 and the first, and the third should be between the second - 5 and the second?
Or, how to generate test cases that dynamically can depend on the previous generated values?
First thought was to write constructors to Shape that check that inputs are valid (e.g. the bullet points above), but the problem of duplicate test case generation would remain with that approach.
The above code uses similar solution as in
SmallCheck invariant -answer.
This Haskell program prints "1.0" How can I get it to print "1"?
fact 0 = 1
fact x = x * fact (x-1)
place m n = (fact m) / (fact n) * (fact (m-n))
main = do
print (place 0 0)
By using the / operation, you are asking haskell to use a fractional data type. You probably don't want that in this case. It is preferable to use an integral type such as Int or Integer. So I suggest to do the following:
1. Add a type declaration for the fact function, something like fact :: Integer -> Integer
2. Use quot instead of /.
So your code should look like this:
fact :: Integer -> Integer
fact 0 = 1
fact x = x * fact (x-1)
place :: Integer -> Integer -> Integer
place m n = (fact m) `quot` (fact n) * (fact (m-n))
main = do
print (place 0 0)
Also, as #leftaroundabout pointed out, you probably want to use a better algorithm for computing those binomial numbers.
You could just use round:
print (round $ place 0 0)
This changes the formatting to the one you want. redneb's answer is, however, the right approach.
I am a beginner in Haskell and I am stuck in a simple recursion function.
I am trying to define a function rangeProduct which when given natural numbers m and n returns the product
m*(m+1)...(n-1)*n
The function should return 0 when n is smaller than m.
What I've tried:
rangeProduct :: Int -> Int -> Int
rangeProduct m n
| m > n = 0
| otherwise = m * n * rangeProduct (m+1)(n-1)
But this is wrong because in the otherwise guard, when m gets bigger and n smaller, at some point m will get bigger than n and it will get 0 causing all what it has done so far to get multiplied by zero, resulting in 0 everytime I run the function.
I know the answer is simple but I am stuck. Can anyone help? Thanks!
Why bother incrementing and decrementing at the same time? Just go in one direction:
rangeProduct m n
| m > n = 0
| m == n = n
| otherwise = m * rangeProduct (m + 1) n
Although you could easily define this without recursion as
rangeProduct :: Integer -> Integer -> Integer
rangeProduct m n
| m > n = 0
| otherwise = product [m..n]
The Following code:
unSum :: Float -> Float
unSum x = (y + y`mod`2 + 2) / 2
where
y = x*(x+1) / 2
gives me this error when I try to load it into WinHugs 98:
Hugs> :load "D:\\kram\\unSumme2.hs"
ERROR file:.\unSumme2.hs:2 - Instance of Integral Float required for definition of unSumme2
What's the essence of this and how am I to do it? Anyway, I dont now if it serves my porpuse, I want to calculate the sum of the uneven numbers until x without recursivity.
It's because you're using mod. The definition of mod, from the Standard Prelude:
class (Real a, Enum a) => Integral a where
[...]
div, mod :: a -> a -> a
[...]
n `mod` d = r where (q,r) = divMod n d
In other words, it expects a to be of the numeric typeclass Integral, which includes only whole numbers.
If you want to stick with Floats, try using mod', from Data.Fixed, per this answer.
Alternatively, if you just want to do integer division, you could change your function's signature to
unSum :: Int -> Int
or similar.