Implementing the ruler function using `streamInterleave` - haskell

I am doing the homework of CIS 194. The problem is to implement the ruler function by using streamInterleave. The code looks like
data Stream a = Cons a (Stream a)
streamRepeat :: a -> Stream a
streamRepeat x = Cons x (streamRepeat x)
streamMap :: (a -> b) -> Stream a -> Stream b
streamMap f (Cons x xs) = Cons (f x) (streamMap f xs)
streamInterleave :: Stream a -> Stream a -> Stream a
streamInterleave (Cons x xs) ys = Cons x (streamInterleave ys xs)
ruler :: Stream Integer
ruler = streamInterleave (streamRepeat 0) (streamMap (+1) ruler)
I am really confused why ruler can be implemented like this. Is this going to give me [0,1,0,1....]?
Any help will be greatly appreciated. Thank you!!

Firstly, we'll represent a Stream like this:
a1 a2 a3 a4 a5 ...
Now, let's take the definition of ruler apart:
ruler :: Stream Integer
ruler = streamInterleave (streamRepeat 0) (streamMap (+1) ruler)
In Haskell, an important point is laziness; that is, stuff doesn't need to be evaluated until it needs to be. This is important here: it's what makes this infinitely recursive definition work. So how do we understand this? We'll start with the streamRepeat 0 bit:
0 0 0 0 0 0 0 0 0 ...
Then this is fed into a streamInterleave, which interleave this the with (as yet unknown) stream from streamMap (+1) ruler (represented with xs):
0 x 0 x 0 x 0 x 0 x 0 x ...
Now we'll start filling in those xs. We know already that every second element of ruler is 0, so every second element of streamMap (+1) ruler must be 1:
1 x 1 x 1 x 1 x 1 x ... <--- the elements of (streamMap (+1) ruler)
0 1 0 x 0 1 0 x 0 1 0 x 0 1 0 x 0 1 0 x ... <--- the elements of ruler
Now we know every second element out of each group of four (so numbers 2,6,10,14,18,...) is 1, so the corresponding elements of streamMap (+1) ruler must be 2:
1 2 1 x 1 2 1 x 1 2 ... <--- the elements of (streamMap (+1) ruler)
0 1 0 2 0 1 0 x 0 1 0 2 0 1 0 x 0 1 0 2 ... <--- the elements of ruler
Now we know that every fourth element out of each group of eight (so numbers 4,12,20,...) is 2 so the corresponding elements of streamMap (+1) ruler must be 3:
1 2 1 3 1 2 1 x 1 2 ... <--- the elements of (streamMap (+1) ruler)
0 1 0 2 0 1 0 3 0 1 0 2 0 1 0 x 0 1 0 2 ... <--- the elements of ruler
And we can continue building ruler like this ad infinitum, by substituting back each n/2, 3n/2, 5n/2, ... numbered value of ruler.

In Haskell notation, with [] in place of Stream (which is isomorphic to infinite lists),
ruler = interleave (repeat 0)
(map (+1) ruler)
[ruler !! i | i <- [0..]] == concat . transpose $
[ repeat 0
, map (+1) ruler]
Splitting the ruler into two alternating sub-sequences to match, we get
[ruler !! 2*i | i <- [0..]] == repeat 0
== [0 | i <- [0..]] -- {0} --
[ruler !! 2*i+1 | i <- [0..]] == map (+1) ruler
== map (+1) $ concat . transpose $
[ [ruler !! 2*i | i <- [0..]]
, [ruler !! 2*i+1 | i <- [0..]]]
concat . transpose $ == concat . transpose $
[[ruler !! 2*i+1 | i <- [0,2..]] [ [1 | i <- [0..]]
,[ruler !! 2*i+1 | i <- [1,3..]]] , [1 + ruler !! 2*i+1 | i <- [0..]]]
Splitting again,
[ruler !! 4*i+1 | i <- [0..]] == [1 | i <- [0..]] -- {1} --
[ruler !! 4*i+3 | i <- [0..]] == concat . transpose $
[ [1 + ruler !! 2*i+1 | i <- [0,2..]]
, [1 + ruler !! 2*i+1 | i <- [1,3..]]]
and again,
[ruler !! 8*i+3 | i <- [0..]] == [2 | i <- [0..]] -- {2} --
[ruler !! 8*i+7 | i <- [0..]] == ....
You should be able to see it through from here:
.... 16*i+7 ..... 3 -- {3} --
.... 32*i+15 ..... 4 -- {4} --
.... 64*i+31 .....
....
Thus,
ruler !! 2^(k+1)*i + 2^k - 1 == k , k <- [0..] , i <- [0..]
0: i => 2i
1: 2i+1 => 4i+1
2: 4i+3 => 8i+3
3: 8i+7 => 16i+7
4: 16i+15 => ....
5:

Related

Is this even a function in Haskell ? If so, how should we read it?

In the book of The Haskell Road to Logic, Math and Programming by Doets et.al., at page 103, it is given that
prime :: Integer -> Bool
prime n | n < 1 = error "not a positive integer"
| n == 1 = False
| otherwise = ldp n == n where
ldp = ldpf primes
ldpf (p:ps) m | rem m p == 0 = p
| p^2 > m = m
| otherwise = ldpf ps m
primes = 2 : filter prime [3..]
However, isn't the logic of this function circular ? I mean I think I'm quite comfortable with recursive functions, but I do not think that this is a recursive function. Even if it is, I'm not able to comprehend the logic of it, so my question is that how to read the logic of such a function.
Edit:
The reason why I'm confused is prime function uses the list primes, but to generate that list, we also use the function prime, so it seems that there is a circular logic, or I just do not understand recursive functions with lazy evaluation.
The ldp n == n condition can be equivalently re-written as
ldpf primes n == n
=
null [() | p <- takeWhile (\p -> p^2 <= n) primes, rem n p==0]
=
and [rem n p > 0 | p <- takeWhile (\p -> p^2 <= n) primes]
so for any given n, the call prime n = ldp n == n only needs to generate the list
primes = 2 : filter prime [3..]
= 2 : filter (\n -> ldpf primes n == n) [3..]
= 2 : filter (\n -> and [rem n p > 0
| p <- takeWhile (\p -> p^2 <= n) primes])
[3..]
up to the smallest prime number q > floor (sqrt $ fromIntegral n), and for that only the primes not greater than q's square root are needed. And to generate those, only the numbers not greater than the square root of that were needed. Pretty soon we end up not needing any primes at all, e.g.
prime 3
=
ldpf primes 3 == 3
=
and [rem 3 p > 0 | p <- takeWhile (\p -> p^2 <= 3) (2 : filter prime [3..])]
=
and [rem 3 p > 0 | p <- takeWhile (<= 3) (4 :
map (\p -> p^2) (filter prime [3..]))]
=
and [rem 3 p > 0 | p <- []]
=
and []
=
True
because 2 already fails the predicate: (2^2 <= 3) = (4 <= 3) = False.
And when testing 4, primes will be probed for containing the number 3, but that's OK as we've just seen above:
prime 4
=
and [rem 4 p > 0 | p <- takeWhile (\p -> p^2 <= 4) primes]
=
and [rem 4 p > 0 | p <- takeWhile (<= 4) (4 :
map (\p -> p^2) (filter prime [3..]))]
=
and [rem 4 p > 0 | p <- 4 : takeWhile (<= 4) (9 :
map (\p -> p^2) (filter prime [4..]))]
=
and [rem 4 p > 0 | p <- 4 : []]
=
False
and we can check it at the GHCi prompt after that,
> :sprint primes
2 : 3 : _
(for the above to work you'll need to take primes out of the prime function and make it a top-level entity in its own right).

List-comprehension output not what I assumed

I assume its simple as its in a past paper of my university but the function is:
[(x,y) | x <- [0..2], y<-[0,x])
and the output
[(0,0),(0,0),(1,0), (1,1), (2,0), (2,2)]
The (2,0) confuses me, if y maps to 0 to x whilst x is equal to 1 = (1,1) wouldnt it be
[(0,0),(0,0),(1,0), (1,1), **(2,1)**, (2,2)]
or is it because due to the y using all its numbers in its list [0,1] it reverts back to 0?
case [(x,y) | x <- [0..2], y<-[0,x]]
[0,x] is:
[0,0] for x=0
[0,1] for x=1
[0,2] for x=2
so if you pair each of those ys up with the corresponding x you get:
[(0,0),(0,0)] -- x = 0
++ [(1,0),(1,1)] -- x = 1
++ [(2,0),(2,2)] -- x = 2
which yields your given output
note: [0,2] has length 2 and is quite different from [0..2] which has length 3 and contains 1
case [(x,y) | x <- [0..2], y<-[0..x]]
it's not that different - [0..x] is:
[0] for x=0
[0,1] for x=1
[0,1,2] for x=2
and if you pair each of those ys up with the corresponding x you get
[(0,0))] -- x = 0
++ [(1,0),(1,1)] -- x = 1
++ [(2,0),(2,1),(2,2)] -- x = 2
which then would give you the result
[(0,0),(1,0),(1,1),(2,0),(2,1),(2,2)]

Pretty Printing list of lists

I have a list of lists:
[[5,1,0,0,5,5,0,0],[0,0,1,4,2,0,6,1],[1,1,6,3,0,1,0,0],[1,5,0,0,0,1,1,6]]
and a string "wxyz"
I would like to have:
1)
w: 5 1 0 0 5 5 0 0
x: 0 0 1 4 2 0 6 1
y: 1 1 6 3 0 1 0 0
z: 1 5 0 0 0 1 1 6
I wrote:
f c xs = putStrLn (c : ':' : ' ' : concat (intersperse " " $ map show xs))
to write one line
and 2)
g xxs c = mapM_ (f c) xxs
How can I modify 2) to loop through string "wxyz" in order to have 1) ?
Instead of mapM_, you can use zipWithM_ from Control.Monad:
g xss cs = zipWithM_ f cs xss
or, if you change the order of arguments in either f or g to match, you can do it with less "points":
g = zipWithM_ f
Also, concat (intersperse " " ...) is otherwise known as unwords ....
You can use zip and uncurry:
g xxs c = mapM_ (uncurry f) (zip xxs c)

Haskell program that gives pretty prime numbers

I've made a haskell program that computes pretty prime numbers. Pretty primes are primes that are very close to a power of 2. You give 2 numbers for example: 10 and 20 then it returns 17 because 17 is the closest to a power of 2. 17 - 16 = 1 so it is the closest.
I've made this:
EDIT: I've rewrote the primefunction like this and e verw function but still getting -1.
-- Geeft priemgetallen terug tussen de 2 grenzen
-- English: Gives primenumbers between 2 numbers
priemgetallen :: Int->[Int]
priemgetallen b = take b (zeef [2..])
where zeef (p:xs) = p : zeef [x | x<-xs, (mod x p) /= 0]
-- Geeft machten terug tussen de 2 grenzen
-- English: Gives powers of 2 between 2 numbers
machten :: Int->Int->[Int]
machten a b
| a <= 2 = 2:[2^x| x<-[2..b], (2^x) `mod` 2 == 0, 2^x < b, 2^x > a]
| otherwise = [2^x| x<-[2..b], (2^x) `mod` 2 == 0, 2^x < b, 2^x > a]
-- English: the start of the function
prettyprime :: Int->Int->Int
prettyprime a b = vergelijk ( verw a (priemgetallen b)) (machten a b)
-- Filter the list
verw :: Int->[Int]->[Int]
verw _ [] = []
verw k (x:xs)
| x > k = [x] ++ verw k xs
| otherwise = verw k xs
-- Vergelijkt alle priemgetallen en geeft welke korste bij het ander ligt
-- English this function must see what primenumber is the closest to a power of 2 but I can't fix it
vergelijk :: [Int]->[Int]->Int
vergelijk [] _ = -1
vergelijk _ [] = -1
vergelijk (x:xs) (y:ys)
| x - y < vergelijk (x:xs) ys = x
| x - y > vergelijk (x:xs) ys = vergelijk xs (y:ys)
| x - y == vergelijk (x:xs) ys = x
main = do
print $ prettyprime 14 20
Can someone help me?
Kind regards,
The incomplete pattern is because you've omitted the case when x - y == vergelijk (x:xs) ys. The compiler is capable of warning you about this if you add -fwarn-incomplete-patterns and convert your guards into a real case:
vergelijk (x:xs) (y:ys) = case compare (x - y) (vergelijk (x:xs) ys) of
LT -> x
-- you will get a warning about having no case for EQ
GT -> vergelijk xs (y:ys)
As a bonus, this version is much less likely to recompute the recursive call, especially on low optimization levels.

FizzBuzz cleanup

I'm still learning Haskell, and I was wondering if there is a less verbose way to express the below statement using 1 line of code:
map (\x -> (x, (if mod x 3 == 0 then "fizz" else "") ++
if mod x 5 == 0 then "buzz" else "")) [1..100]
Produces:
[(1,""),(2,""),(3,"fizz"),(4,""),(5,"buzz"),(6,"fizz"),(7,""),(8,""),(9,"fizz"),(10,"buzz"),(11,""),(12,"fizz"),(13,""),(14,""),(15,"fizzbuzz"),(16,""),(17,""),(18,"fizz"),(19,""),(20,"buzz"),(21,"fizz"),(22,""),(23,""),(24,"fizz"),(25,"buzz"),(26,""),(27,"fizz"),(28,""),(29,""),(30,"fizzbuzz"), etc
It just feels like I'm fighting the syntax more than I should. I've seen other questions for this in Haskell, but I'm looking for the most optimal way to express this in a single statement (trying to understand how to work the syntax better).
We need no stinkin' mod...
zip [1..100] $ zipWith (++) (cycle ["","","fizz"]) (cycle ["","","","","buzz"])
or slightly shorter
import Data.Function(on)
zip [1..100] $ (zipWith (++) `on` cycle) ["","","fizz"] ["","","","","buzz"]
Or the brute force way:
zip [1..100] $ cycle ["","","fizz","","buzz","fizz","","","fizz","buzz","","fizz","","","fizzbuzz"]
If you insist on a one-liner:
[(x, concat $ ["fizz" | mod x 3 == 0] ++ ["buzz" | mod x 5 == 0]) | x <- [1..100]]
How's about...
fizzBuzz = [(x, fizz x ++ buzz x) | x <- [1..100]]
where fizz n | n `mod` 3 == 0 = "fizz"
| otherwise = ""
buzz n | n `mod` 5 == 0 = "buzz"
| otherwise = ""
Couldn't resist going in the other direction and making it more complicated. Look, no mod...
merge as#(a#(ia,sa):as') bs#(b#(ib,sb):bs') =
case compare ia ib of
LT -> a : merge as' bs
GT -> b : merge as bs'
EQ -> (ia, sa++sb) : merge as' bs'
merge as bs = as ++ bs
zz (n,s) = [(i, s) | i <- [n,2*n..]]
fizzBuzz = foldr merge [] $ map zz [(1,""), (3,"fizz"), (5,"buzz")]
Along the same lines as larsmans' answer:
fizzBuzz = [(x, f 3 "fizz" x ++ f 5 "buzz" x) | x <- [1..100]]
where f k s n | n `mod` k == 0 = s
| otherwise = ""
I think the reason why you feel like you are fighting the syntax is because you are mixing too many types.
Instead of trying to print:
[(1, ""), (2,""), (3,"Fizz")...]
Just think of printing strings:
["1","2","Fizz"...]
My attempt:
Prelude> let fizzBuzz x | x `mod` 15 == 0 = "FizzBuzz" | x `mod` 5 == 0 = "Buzz" | x `mod` 3 == 0 = "Fizz" | otherwise = show x
Prelude> [fizzBuzz x | x <-[1..100]]
["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz"...]
In order to convert an Int to String you use the:
show x
Just for studying
zipWith (\a b -> b a) (map show [1..100]) $ cycle [id,id,const "fizz",id,const "buzz",const "fizz",id,id,const "fizz",const "buzz",id,const "fizz",id,id,const "fizzbuzz"]
produces
["1","2","fizz","4","buzz","fizz","7","8","fizz","buzz","11","fizz","13","14","fizzbuzz","16","17","fizz","19","buzz","fizz","22","23","fizz","buzz","26","fizz","28","29","fizzbuzz","31","32","fizz","34","buzz","fizz","37","38","fizz","buzz","41","fizz","43","44","fizzbuzz","46","47","fizz","49","buzz","fizz","52","53","fizz","buzz","56","fizz","58","59","fizzbuzz","61","62","fizz","64","buzz","fizz","67","68","fizz","buzz","71","fizz","73","74","fizzbuzz","76","77","fizz","79","buzz","fizz","82","83","fizz","buzz","86","fizz","88","89","fizzbuzz","91","92","fizz","94","buzz","fizz","97","98","fizz","buzz"]
Writer monad may look nice (if you don't like concat):
fizzBuzz = [(x, execWriter $ when (x `mod` 3 == 0) (tell "fizz") >> when (x `mod` 5 == 0) (tell "buzz")) | x <- [1..100]]
It's not particularly succinct though.

Resources