Related
--for number divisible by 15 we can get it easily
take 10 [x | x <- [1..] , x `mod` 15 == 0 ]
--but for all how do I use the all option
take 10 [x | x <- [1..] , x `mod` [2..15] == 0 ]
take 10 [x | x <- [1..] , all x `mod` [2..15] == 0 ]
I want to understand how to use all in this particular case.
I have read Haskell documentation but I am new to this language coming from Python so I am unable to figure the logic.
First you can have a function to check if a number is mod by all [2..15].
modByNumbers x ns = all (\n -> x `mod` n == 0) ns
Then you can use it like the mod function:
take 10 [x | x <- [1..] , x `modByNumbers` [2..15] ]
Alternatively, using math, we know that the smallest number divible by all numbers less than n is the product of all of the prime numbers x less than n raised to the floor of the result of logBase x n.
A basic isPrime function:
isPrime n = length [ x | x <- [2..n], n `mod` x == 0] == 1
Using that to get all of the primes less than 15:
p = [fromIntegral x :: Float | x <- [2..15], isPrime x]
-- [2.0,3.0,5.0,7.0,11.0,13.0]
Now we can get the exponents:
e = [fromIntegral (floor $ logBase x 15) :: Float | x <- p']
-- [3.0,2.0,1.0,1.0,1.0,1.0]
If we zip these together.
z = zipWith (**) p e
-- [8.0,9.0,5.0,7.0,11.0,13.0]
And then find the product of these we get the smallest number divisible by all numbers between 2 and 15.
smallest = product z
-- 360360.0
And now to get the rest we just need to multiply that by the numbers from 1 to 15.
map round $ take 10 [smallest * x | x <- [1..15]]
-- [360360,720720,1081080,1441440,1801800,2162160,2522520,2882880,3243240,3603600]
This has the advantage of running substantially faster.
Decompose the problem.
You already know how to take the first 10 elements of a list, so set that aside and forget about it. There are infinitely many numbers divisible by all of [2,15], your remaining task is to list them all.
There are infinitely many natural numbers (unconstrained), and you already know how to list them all ([1..]), so your remaining task is to transform that list into the "sub-list" who's elements are divisible by all of [2,15].
You already know how to transform a list into the "sub-list" satisfying some constraint (predicate :: X -> Bool). You're using a list comprehension in your posted code, but I think the rest of this is going to be easier if you use filter instead. Either way, your remaining task is to represent "is divisible by all of [2,15]" as a predicate..
You already know how to check if a number x is divisible by another number y. Now for something new: you want to abstract that as a predicate on x, and you want to parameterize that predicate by y. I'm sure you could get this part on your own if asked:
divisibleBy :: Int -> (Int -> Bool)
divisibleBy y x = 0 == (x `mod` y)
You already know how to represent [2,15] as [2..15]; we can turn that into a list of predicates using fmap divisibleBy. (Or map, worry about that difference tomorrow.) Your remaining task is to turn a list of predicates into a predicate.
You have a couple of options, but you already found all :: (a -> Bool) -> [a] -> Bool, so I'll suggest all ($ x). (note)
Once you've put all these pieces together into something that works, you'll probably be able to boil it back down into something that looks a little bit like what you first wrote.
To give overall context, I have a 2d grid of size N (the size is known but can vary and is always a square i.e x axis = y axis) and M points on the grid that I'm trying to find (the amount of points is known but their locations are not). I want to iterate through every possible solution for said grid. Also the points don't have to be in a specific order, so
[(1,1),(1,2)]
is the same as
[(1,2),(1,1)]
So for example assume the grid was a 2x2 and their was 2 points. Then all the possible solutions would be
[(1,1),(1,2)]
[(1,1),(2,1)]
[(1,1),(2,2)]
[(1,2),(2,1)]
...and so on...
I'm trying to create a function that will output these to me.
I know the function below can create me a full grid, but I don't know how to use this to generate all the possible point locaitons. And whether this grid is even useful in the first place
createGrid :: Int -> [(Int, Int)]
createGrid num = [ (x,y) | x <- [1..num], y <- [1..num]]
Any help would be appreciated
It sounds like you just want a list of the unique ways to choose M items from a list (grid) of N*M items. You already know how to generate this list, so all you need is the ways to choose K items from a list. This is a well-trodden path; for example, see Function to generate the unique combinations of a list in Haskell.
In general it is useful to try to do this sort of splitting up: break your program into smaller pieces and see how many of them are easy to solve. If you try to do everything all at once in one function, you end up repeating work and often wind up with a function that is difficult to read.
For a given grid, if m is 0, then we return the empty list, when m is greater than 0, then we yield a point and recurse on the rest of the list, so:
possibleGrids :: Int -> Int -> [[(Int, Int)]]
possibleGrids n mm = go mm 1 0
where go 0 _ _ = [[]]
go m i j = [(x, y) : tl | x <- [i .. n], y <- [1 .. n], x > i || y > j, tl <- go (m-1) x y]
The first parameter here is n, the size of the grid. The second one is m, the number of points to mark. For a 2×2 grid, this gives us:
ghci> possibleGrids 2 0
[[]]
ghci> possibleGrids 2 1
[[(1,1)],[(1,2)],[(2,1)],[(2,2)]]
ghci> possibleGrids 2 2
[[(1,1),(1,2)],[(1,1),(2,1)],[(1,1),(2,2)],[(1,2),(2,1)],[(1,2),(2,2)],[(2,1),(2,2)]]
The code uses symmetry breaking, so it will not mark twice (or more) the same point, nor will it provide the list of points in a different order.
I wrote a solution for a very simple practice problem:
Calculate the number of grains of wheat on a chessboard given that the number on each square doubles. Write code that shows how many grains are on a given square, and the total number of grains on the chessboard.
The function must return a Maybe Integer and return Nothing if the input is less than 1 or greater than 64.
square :: Integer -> Maybe Integer
square n = if (n < 1 || n > 64) then Nothing else Just (2^(pred n))
total :: Integer
total = sum (fmap sum (map square [1..64]))
I tried to apply fmap sum to some test output of map square (list of Maybe Integer) in GHCI and was surprised to discover it returns the list of integers (sans Just) rather than their sum. So in the solution above I apply sum a second time to actually get the sum.
I would like to understand conceptually why this is the case: in other words why is sum behaving like a converter for Maybe Ints to Ints in this context instead of adding things?
I've solved some similar exercises relying on helper functions to avoid complications of doing computation on Maybe values, and perhaps in this case I should just calculate the value of total without utilizing square, i.e.:
total = sum [2^n | n <- [0..63]]
However since I'd already written a useful function my first instinct was to reuse it, which led to some unforeseen behavior.
Let's look at the type of sum:
sum :: (Foldable t, Num a) => t a -> a
Often, for a beginner, this is simplified by assuming that t ~ [], so that we instead use sum as
sum :: Num a => [a] -> a
If we try to use sum at this type in your example, we will get a type error, because you have a list of Maybe numbers, not a list of numbers. Instead you write fmap sum [Just 1], specializing sum and fmap to:
sum :: Maybe Integer -> Integer
fmap :: (Maybe Integer -> Integer) -> [Maybe Integer] -> [Integer]
So the question isn't really "why isn't sum adding things", so much as "how can sum have a meaningful definition when given a single Maybe Integer?"
One way to answer that question, if you're not familiar with how to interpret sum as working on Foldable or how Maybe is foldable, is to just try implementing it yourself. There's really only one reasonable implementation:
sum :: Maybe Integer -> Integer
sum Nothing = 0
sum (Just x) = x
Right? Someone asked you "what's the total of the numbers in here", and then gave you either zero or one number. Pretty easy to add up. That's exactly how sum works for Maybe, except that it goes through Foldable instead of being specialized to Maybe.
After this, of course it's easy: you've turned your [Maybe Integer] into an [Integer], and of course summing that gets you the sum of the non-Nothing entries.
Let's look at an example.
map square [0..2] = [Nothing, Just 1, Just 2]
fmap sum (map square [0..2]) = [sum Nothing, sum (Just 1), sum (Just 2)]
Since Maybe is a Foldable container, it makes sense to calculate the sum of its elements:
sum Nothing = 0
sum (Just a) = a
So
fmap sum (map square [0..2]) = [0, 1, 2]
Now I don't know what you were actually hoping to do with the Maybes, but this is why you got what you got.
One thing worth internalising; when you map a function over a list1, the result is always going to be a list with the same number of elements. The function will be applied to each element of the list individually; it cannot combine them into a single summary value. That's just not what fmap does.
So with that principle in mind, we know that fmap sum squares (where squares = map square [1..64]) cannot possibly result in the sum of squares. It's going to be [ sum (square 1), sum (square 2), ... , sum (square 64) ]. We will then need to apply sum again to that whole list, if we want to actually add them up.
That just leaves an explanation for what sum (square 1) etc is actually doing (i.e. what sum does when applied to Maybe values). The proper type for sum is sum :: (Foldable t, Num a) => t a -> a. Foldable is basically the type-class of structures that you can scan for 0 or more elements in order (essentially: those you can convert to a list). All sum does is add up the elements that are there, however many there are (and use 0 as a "starting value" in case there are no elements). Maybe has a Foldable instance; it always has 0 or 1 elements, and sum can add those up just as well as it can add up lists that happen to have only 0 or 1 elements.
Of course the effect of summing zero-or-one numbers is just that the result is 0 if there were zero inputs and equal the input number if there was one. + never actually gets called for this "sum", which makes it feel a little pointless. But sum didn't know that; it works for any Foldable, regardless of how many elements they contain. And Maybe didn't know that it would end up being used to "sum without actually adding"; it just implemented Foldable so that any other function that wants to scan a variable number of elements out of a structure can scan Maybes.
If you think it's silly, just don't use sum for that job; use fromMaybe 0 instead.
1 You can generalise this to other functors beyond lists; when you fmap a function over a data structure, the result will have exactly the same structure as the input. Only the "leaf nodes" will be different.
First of all, the fmap in
total = sum (fmap sum (map square [1..64]))
is just map:
total = sum ( map sum (map square [1..64]))
and the maps compose by composing their mapping functions,
total = sum ( map (sum . square) [1..64] )
and a map applies its function to each element of the list,
total = sum [sum (square x) | x <- [1..64] ]
while a composed function finds its result in steps,
total = sum [sum y | x <- [1..64], y <- [square x] ]
whereas the inner sum is working with the result of square, namely, a Maybe number,
total = sum [ n | x <- [1..64], Just n <- [square x] ]
= sum [ n | x <- [1..64], Just n <- list (square x) ]
where list y = [y]
and turning sum y into just n works because sum finds a sum and 0 is its identity, so adding a 0 is the same as not adding anything at all. Meaning, the Just n pattern match fails when square produces a Nothing (which in our case is never, but never mind that) so that x which causes it is skipped over.
total = sum [ n | x <- [1..64], n <- maybeToList (square x) ]
= sum [ n | x <- [1..64], n <- case (square x) of
Just n -> [n]
Nothing -> [] ]
But again, we know that this never happens, and all this repackaging of the same number is all for naught, so in the end your code is equivalent to
total = sum [ n | x <- [1..64], Just n <- [Just (2^(x-1))] ]
= sum [ n | x <- [1..64], n <- [ 2^(x-1) ] ]
= sum [ 2^(x-1) | x <- [1..64] ]
just as you intended.
Seeing is better than believing (well, remembering / imagining, which is needed when using higher order functions ... unless of course one has an eidetic memory so for them believing is seeing). It might even give us new ideas for further code simplification, some transformations, and, eventually, maybe even some computational optimizations:
total = sum [ 2^x | x <- [0..63] ]
= sum [ product (replicate x 2) | x <- [0..63] ]
= sum $ [ product (replicate 0 2) ]
++ [ product (replicate x 2) | x <- [1..63] ]
= sum $ [ product [] ]
++ [ 2 * product (replicate (x-1) 2) | x <- [1..63] ]
= sum $ [ 1 ]
++ [ 2 * product (replicate x 2) | x <- [0..62] ]
= sum [1] + sum ( [2*n0] ++
[ 2 * product (replicate x 2) | x <- [1..62] ] )
where { n0=1 }
= n0 + sum [n1] + sum( [2*n1] ++
[ 2 * product (replicate x 2) | x <- [2..62] ] )
where { n0=1 ; n1=2*n0 }
= n0 + n1 + n2 + sum( [2*n2] ++
[ 2 * product (replicate x 2) | x <- [3..62] ] )
where { n0=1 ; n1=2*n0 ; n2=2*n1 }
= ....
= sum . take 64 $ iterate (2*) 1
And there they are again, the 64 squares of the chess board, and the first single grain of rice, which is doubled, and doubled again, as we ago along the squares.
I'm trying to understand how paralleling in Haskell works and I've found following example in Control.Parallel docs.
import Control.Parallel
-- Equation for the upper hemisphere of the unit circle
circle :: Double -> Double
circle x = sqrt (abs(1 - x^2))
-- Calculate the area of a right-handed Riemann rectangle
area :: Double -> Double -> Double
area x1 x2 = (x2 - x1) * circle x2
-- Recursively add the areas of the Riemann rectangles
parEstimate :: [Double] -> Double
parEstimate (x:[]) = 0
parEstimate (x:y:[]) = area x y
parEstimate (x:y:xs) =
smaller `par` (larger `pseq` smaller + larger)
where smaller = area x y
larger = parEstimate (y:xs)
But I couldn't find an explanation of how this recursion works: parEstimate (x:y:xs), cause all examples I've found contains only two arguments.
That's why I cannot find out how to run this function. That's how I do:
main = print (parEstimate [1.0, 2.0])
but not sure, if it's correct.
Also I would like to implement function calculating definite integral based on this example.
The recursion, essentially, is a simple fold-like recursion scheme; if this were purely sequential, you might write it as
seqEstimate :: [Double] -> Double
seqEstimate (x:[]) = 0
seqEstimate (x:y:[]) = area x y
seqEstimate (x:y:xs) = smaller + larger
where smaller = area x y
larger = seqEstimate (y:xs)
(In fact, you would probably just use zipWith instead: seqEstimate xs = sum (zipWith area xs (tail xs)).)
The parallelized version is similar. This time, though, par is used to indicate that the left-hand side (smaller) can be evaluated in parallel with the right-hand side (pseq larger (smaller + larger)). Whether or not the compiler chooses to do so, and regardless of whether smaller completes before or after larger, the sum of smaller + larger will be correctly computed.
I am trying to generate all possible combinations of n numbers. For example if n = 3 I would want the following combinations:
(0,0,0), (0,0,1), (0,0,2)... (0,0,9), (0,1,0)... (9,9,9).
This post describes how to do so for n = 3:
[(a,b,c) | m <- [0..9], a <- [0..m], b <- [0..m], c <- [0..m] ]
Or to avoid duplicates (i.e. multiple copies of the same n-uple):
let l = 9; in [(a,b,c) | m <- [0..3*l],
a <- [0..l], b <- [0..l], c <- [0..l],
a + b + c == m ]
However following the same pattern would become very silly very quickly for n > 3. Say I wanted to find all of the combinations: (a, b, c, d, e, f, g, h, i, j), etc.
Can anyone point me in the right direction here? Ideally I'd rather not use a built in funtion as I am trying to learn Haskell and I would rather take the time to understand a peice of code than just use a package written by someone else. A tuple is not required, a list would also work.
My other answer gave an arithmetic algorithm to enumerate all the combinations of digits. Here's an alternative solution which arises by generalising your example. It works for non-numbers, too, because it only uses the structure of lists.
First off, let's remind ourselves of how you might use a list comprehension for three-digit combinations.
threeDigitCombinations = [[x, y, z] | x <- [0..9], y <- [0..9], z <- [0..9]]
What's going on here? The list comprehension corresponds to nested loops. z counts from 0 to 9, then y goes up to 1 and z starts counting from 0 again. x ticks the slowest. As you note, the shape of the list comprehension changes (albeit in a uniform way) when you want a different number of digits. We're going to exploit that uniformity.
twoDigitCombinations = [[x, y] | x <- [0..9], y <- [0..9]]
We want to abstract over the number of variables in the list comprehension (equivalently, the nested-ness of the loop). Let's start playing around with it. First, I'm going to rewrite these list comprehensions as their equivalent monad comprehensions.
threeDigitCombinations = do
x <- [0..9]
y <- [0..9]
z <- [0..9]
return [x, y, z]
twoDigitCombinations = do
x <- [0..9]
y <- [0..9]
return [x, y]
Interesting. It looks like threeDigitCombinations is roughly the same monadic action as twoDigitCombinations, but with an extra statement. Rewriting again...
zeroDigitCombinations = [[]] -- equivalently, `return []`
oneDigitCombinations = do
z <- [0..9]
empty <- zeroDigitCombinations
return (z : empty)
twoDigitCombinations = do
y <- [0..9]
z <- oneDigitCombinations
return (y : z)
threeDigitCombinations = do
x <- [0..9]
yz <- twoDigitCombinations
return (x : yz)
It should be clear now what we need to parameterise:
combinationsOfDigits 0 = return []
combinationsOfDigits n = do
x <- [0..9]
xs <- combinationsOfDigits (n - 1)
return (x : xs)
ghci> combinationsOfDigits' 2
[[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[0,9],[1,0],[1,1] ... [9,8],[9,9]]
It works, but we're not done yet. I want to show you that this is an instance of a more general monadic pattern. First I'm going to change the implementation of combinationsOfDigits so that it folds up a list of constants.
combinationsOfDigits n = foldUpList $ replicate n [0..9]
where foldUpList [] = return []
foldUpList (xs : xss) = do
x <- xs
ys <- foldUpList xss
return (x : ys)
Looking at the definiton of foldUpList :: [[a]] -> [[a]], we can see that it doesn't actually require the use of lists per se: it only uses the monad-y parts of lists. It could work on any monad, and indeed it does! It's in the standard library, and it's called sequence :: Monad m => [m a] -> m [a]. If you're confused by that, replace m with [] and you should see that those types mean the same thing.
combinationsOfDigits n = sequence $ replicate n [0..9]
Finally, noting that sequence . replicate n is the definition of replicateM, we get it down to a very snappy one-liner.
combinationsOfDigits n = replicateM n [0..9]
To summarise, replicateM n gives the n-ary combinations of an input list. This works for any list, not just a list of numbers. Indeed, it works for any monad - though the "combinations" interpretation only makes sense when your monad represents choice.
This code is very terse indeed! So much so that I think it's not entirely obvious how it works, unlike the arithmetic version I showed you in my other answer. The list monad has always been one of the monads I find less intuitive, at least when you're using higher-order monad combinators and not do-notation.
On the other hand, it runs quite a lot faster than the number-crunching version. On my (high-spec) MacBook Pro, compiled with -O2, this version calculates the 5-digit combinations about 4 times faster than the version which crunches numbers. (If anyone can explain the reason for this I'm listening!)
What are all the combinations of three digits? Let's write a few out manually.
000, 001, 002 ... 009, 010, 011 ... 099, 100, 101 ... 998, 999
We ended up simply counting! We enumerated all the numbers between 0 and 999. For an arbitrary number of digits this generalises straightforwardly: the upper limit is 10^n (exclusive), where n is the number of digits.
Numbers are designed this way on purpose. It would be jolly strange if there was a possible combination of three digits which wasn't a valid number, or if there was a number below 1000 which couldn't be expressed by combining three digits!
This suggests a simple plan to me, which just involves arithmetic and doesn't require a deep understanding of Haskell*:
Generate a list of numbers between 0 and 10^n
Turn each number into a list of digits.
Step 2 is the fun part. To extract the digits (in base 10) of a three-digit number, you do this:
Take the quotient and remainder of your number with respect to 100. The quotient is the first digit of the number.
Take the remainder from step 1 and take its quotient and remainder with respect to 10. The quotient is the second digit.
The remainder from step 2 was the third digit. This is the same as taking the quotient with respect to 1.
For an n-digit number, we take the quotient n times, starting with 10^(n-1) and ending with 1. Each time, we use the remainder from the last step as the input to the next step. This suggests that our function to turn a number into a list of digits should be implemented as a fold: we'll thread the remainder through the operation and build a list as we go. (I'll leave it to you to figure out how this algorithm changes if you're not in base 10!)
Now let's implement that idea. We want calculate a specified number of digits, zero-padding when necessary, of a given number. What should the type of digits be?
digits :: Int -> Int -> [Int]
Hmm, it takes in a number of digits and an integer, and produces a list of integers representing the digits of the input integer. The list will contain single-digit integers, each one of which will be one digit of the input number.
digits numberOfDigits theNumber = reverse $ fst $ foldr step ([], theNumber) powersOfTen
where step exponent (digits, remainder) =
let (digit, newRemainder) = remainder `divMod` exponent
in (digit : digits, newRemainder)
powersOfTen = [10^n | n <- [0..(numberOfDigits-1)]]
What's striking to me is that this code looks quite similar to my English description of the arithmetic we wanted to perform. We generate a powers-of-ten table by exponentiating numbers from 0 upwards. Then we fold that table back up; at each step we put the quotient on the list of digits and send the remainder to the next step. We have to reverse the output list at the end because of the right-to-left way it got built.
By the way, the pattern of generating a list, transforming it, and then folding it back up is an idiomatic thing to do in Haskell. It's even got its own high-falutin' mathsy name, hylomorphism. GHC knows about this pattern too and can compile it into a tight loop, optimising away the very existence of the list you're working with.
Let's test it!
ghci> digits 3 123
[1, 2, 3]
ghci> digits 5 10101
[1, 0, 1, 0, 1]
ghci> digits 6 99
[0, 0, 0, 0, 9, 9]
It works like a charm! (Well, it misbehaves when numberOfDigits is too small for theNumber, but never mind about that.) Now we just have to generate a counting list of numbers on which to use digits.
combinationsOfDigits :: Int -> [[Int]]
combinationsOfDigits numberOfDigits = map (digits numberOfDigits) [0..(10^numberOfDigits)-1]
... and we've finished!
ghci> combinationsOfDigits 2
[[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[0,9],[1,0],[1,1] ... [9,7],[9,8],[9,9]]
* For a version which does require a deep understanding of Haskell, see my other answer.
combos 1 list = map (\x -> [x]) list
combos n list = foldl (++) [] $ map (\x -> map (\y -> x:y) nxt) list
where nxt = combos (n-1) list
In your case
combos 3 [0..9]