Does the IO Monad evaluate lazily? - haskell

Here is the following code in which I try to found some prime divisors. I have tried to convert TAOCP algorithms to Haskell programs but I can understand when something evaluates lazily or eagerly:
modof2 n = let a0 = shiftR n 1
a1 = shiftL a0 1
in n-a1
iseven n = modof2 n == 0
factoringby2 n = let s=(lastf (takeWhile f [1..])) + 1
d=n `quot` powerof2 s
in (s,d)
where f s = let d = n `quot` (powerof2 s)
in if isodd d
then False
else True
lastf [] = 0
lastf xs = last xs
miller_rabin_prime_test n 0 result=return result
miller_rabin_prime_test n k result| (isodd n) && n>3 = do
a<-randomRIO(2,n-2)
let z = basic_step n a (fst sd) (snd sd)
miller_rabin_prime_test n (k-1) z
where sd=factoringby2 n
basic_step:: Integer->Integer->Int->Integer->Bool
basic_step n a s d =any (\x-> x==1 || x==n-1) (map x (map u [0..s-1]))
where u j=powerof2(j)*d
x j=modular_pow a j n 1
isprime n = if n==2 || n==3
then return True
else if n<2
then return False
else if iseven n
then return False
else miller_rabin_prime_test n 5 True
x_m :: Double->Integer->Integer
x_m 0 n = 2
x_m m n = f (x_m (m-1) n) `mod` n
where f x = x^2 +1
l::Double->Double
l m = 2 ^ (floor (log2 m))
where log2 m = log m / log 2
g m n = let a = x_m m n
b = x_m ((l m)-1) n
in gcd (a-b) n
gg n = [g m n|m<-[1..]]
algorithmB n = do
testprime<-isprime n
let a = head (filter (1>) (gg n))
c<-algorithmB (n `div` a)
if testprime
then return []
else return (a:c)
algorithmB does not terminate. Why this happens? I think that c<-algorithmB (n div a) is the reason because it does not evaluate lazily. Is that true?
Thanks

algorithmB calls itself in an infinite loop. Of course it doesn't return!

Related

What's the difference between tail and guarded recursion?

In my exercise I have to decide what kind of recursion the functions are.
We have to choose from linear recursion, tail recursion and guarded recursion
but I don't really understand the difference between the last two.
Can some one explain the difference between guarded and tail recursion?
The functions we have to differentiate for reference:
pow2 0 = 1
pow2 n = 2 * pow2 (n-1)
factAux r i n
| i <= n = factAux (i * r) (i + 1) n | otherwise = r
factorial = factAux 1 1
init [x] = []
init (x:xs) = x : init xs
binom n 0 = 1
binom n k
| n == k = 1
| otherwise = binom (n - 1) k + binom (n - 1) (k - 1)
negList [] = []
negList (x : xs) = if x > 0 then negList (-x : xs) else x : negList xs
I won't solve your homework as it would be counter-educative.
Instead, I will answer the question in the post's title:
Tail recursion
A call is tail-recursive when
It's recursive
The result of that call is returned immediately, without any modification or action done after it
For example:
-- This is tail-rec
f x = if x == 0
then 0
else f (x + 1)
-- This is not
g x = if x == 0
then 0
else g (x + 1) - 1
-- And this is not too
h x = h (h x)
For more info, check this thread.
Guarded recursion
This occurs when a recursive call is positioned under a lazy parameter to a data constructor:
-- This is guarded-rec
f x = if x == 0
then []
else x : f (x - 1) -- (:) is lazy on both operands
-- And this is not
g x = if x == 0
then []
else g (x - 1)
-- And this is not too
data StrictList a = SNil | SCons !a !(StrictList a)
h x = if x == 0
then SNil
SCons x (h x)
Cross-examples
This link may help you seeing the difference. Also check out this, although it gives examples in Prolog.
Tail rec and guard rec
This is contradictory, as guarding a recursive call with a constructor breaks the "doing nothing to the result" requirement of tail recursion.
Tail rec and not guard rec
f x = f x
Not tail rec and guard rec
f x = x : f x
Not tail rec and not guard rec
f x = f x + 1

Least common multiple without using gcd

With gcd its fairly easy but i do not understand how to tie in all the functions to make it happen without.
kgv :: Int -> Int -> Int
kgv x y = abs ((x `quot` (gcd x y)) * y)
I got this function to find the prime factors which works (prime_factors) and I am working on making a function that takes the maximum number from one list and checks if its on the other list (comp):
prime_factors :: Int -> [Int]
prime_factors 1 = []
prime_factors n
| factors == [] = [n]
| otherwise = factors ++ prime_factors (n `div` (head factors))
where factors = take 1 $ filter (\x -> (n `mod` x) == 0) [2 .. n-1]
comp :: [Int]->Int
comp (ys)(x:xs)
|maximum prime_factors xs elem prime_factors ys == x
|otherwise tail x
kgv :: Int -> Int -> Int
kgv x y = abs ((x `quot` (comp x y)) * y)
Here's an absurdly simple and obscenely inefficient solution:
lcm m n = head [x | x <- [1..], x `rem` m == 0, x `rem` n == 0]
Of course, this relies on two different notions of "least" coinciding under the circumstances, which they do. A fully naive solution doesn't seem possible.
here is the (very) naive algorithm I was talking about:
kgv :: (Ord a, Num a) => a -> a -> a
kgv x y = find x y
where find i j
| i == j = i
| i < j = find (i+x) j
| i > j = find i (j+y)
it's basically what a school-child would do ;)
caution I ignored negative numbers and 0 - you'll probably have to handle those
perhaps another easy way is
import Data.List(intersect)
lcm m n = head $ intersect (series m n) (series n m)
where series a b = take a $ map (*b) [1..]
I figured it out myself mostly. Thanks for the ideas and pointers.
ggt n m | n > m = maximum [t | t <- [1 .. m], gt n m t]
| otherwise = maximum [t | t <- [1 .. n], gt n m t]
gt n m c = t n c && t m c
t n c | n >= c = (mod n c == 0)
| otherwise = False
kgv :: Int -> Int -> Int
kgv x y |x==0=0|y==0=0 |otherwise = abs ((x `quot` (ggt x y)) * y)

How can I extract list of similar elements from a haskell list

Given a list such as [1,0,0,0,3,0,0,0,0,2,4,0,0] and an index, how can I extract consecutive patterns of 0 in Haskell. For example if the given index is between 1 and 3 inclusive, the result is [0,0,0] if it is between 5 and 8 [0,0,0,0] and so on
First, build a list where run lengths are stored for each number:
runs :: (Eq a) => [a] -> [(a, Int)]
runs = map (head &&& length) . group
so e.g.
runs [1,0,0,0,1,0,0,0,0,1,1,0,0] == [(1,1),(0,3),(1,1),(0,4),(1,2),(0,2)]
Then, index into this list by walking it in run length-sized steps:
indexRuns :: Int -> [(a, Int)] -> [a]
indexRuns i [] = error "Index out of bounds"
indexRuns i ((x, l):rs)
| i < l = replicate l x
| otherwise = indexRuns (i - l) rs
You can do this in O(n) time:
extract :: Eq a => Int -> [a] -> [a]
extract _ [] = []
extract idx (x:xs) = extract' x [x] 1 xs
where
extract' _ _ _ [] = [] -- Index out of bounds
extract' v vs n (r : rest)
| idx == n = vs ++ (takeWhile (== v) rest)
| (v == r) = extract' v (r:vs) (n+1) rest
| otherwise = extract' r [r] (n+1) rest
This will count the number of zeros around the index
numZeros::Int->[Int]->Int
numZeros 0 (1:_) = 0
numZeros i (1:rest) = numZeros (i-1) rest
numZeros i theList
| i < zeroLen = zeroLen
| otherwise = numZeros (i-zeroLen) $ drop zeroLen theList
where
zeroLen = length (takeWhile (==0) theList)
You can replicate 0 the appropriate number of times to get the final list.
f = f' (takeWhile (== 0)) where
f' c n xs | n < 0 || null xs = []
f' c n (1:xs) = f (n - 1) xs
f' c 0 xs = c xs
f' c n (0:xs) = f' ((0:) . c) (n - 1) xs
Or even more obfuscated
f n xs = g (splitAt n xs) >>= takeWhile (== 0) where
g (xs, ys#(0:_)) = [reverse xs, ys]
g _ = []
Some tests:
main = mapM_ (\i -> print $ (i, f i [1,0,0,0,1,0,0,0,0,1,1,0,0])) [-1..13]
prints
(-1,[])
(0,[])
(1,[0,0,0])
(2,[0,0,0])
(3,[0,0,0])
(4,[])
(5,[0,0,0,0])
(6,[0,0,0,0])
(7,[0,0,0,0])
(8,[0,0,0,0])
(9,[])
(10,[])
(11,[0,0])
(12,[0,0])
(13,[])

How can I use Haskell Memoize to solve LCS?

Here is the code:
import Data.Function.Memoize
main = do
let
f 0 0 = 0
f 0 _ = 0
f _ 0 = 0
f n m = if a !! n == b !! m
then 1 + f' (n-1) (m-1)
else max (f' (n-1) m) (f' n (m-1))
f' = memoize2 $ f
print $ length a
print $ length b
print $ f (length a - 1) (length b - 1)
where
a = "1234helloworld2ffdfdfdf32rg4364jm5"
b = "03424helloworldfdfdfdfd4353645645jnt"
But the problem is I cannot write the function globally where strings a and b are passed to it as arguments. It seems if I rewrite
f n m
to
f a b n m
and
f' = memoize4 f
the function will speed down.
How can I pass arguments that should not be used in memoization to functions that use memoize?
so I write my global function like this and it does work!
But how can I accumulate the common string it finds and get the final result with this function?
lcs a b = f (length a - 1) (length b - 1)
where
f 0 0 = 0
f 0 _ = 0
f _ 0 = 0
f n m = if a !! n == b !! m
then (1 + f' (n-1) (m-1))
else max (f' (n-1) m) (f' n (m-1))
f' = memoize2 $ f

How to express {2n+3m+1|n,m∈N} in list comprehension form? (N is the set of natural numbers including 0)

How do I express {2n+3m+1|n,m∈N} in list comprehension form? N is the set of natural numbers, including 0.
Shortly:
1:[3..]
Isn't {2n+3m+1|n,m ∈ ℕ} = ℕ - {0,2}?
The following Haskell function will give you all pairs from two lists, even if one or both is infinite. Each pair appears exactly once:
allPairs :: [a] -> [b] -> [(a, b)]
allPairs _ [] = []
allPairs [] _ = []
allPairs (a:as) (b:bs) =
(a, b) : ([(a, b) | b <- bs] `merge`
[(a, b) | a <- as] `merge`
allPairs as bs)
where merge (x:xs) l = x : merge l xs
merge [] l = l
You could then write your list as
[2 * n + 3 * m + 1 | (n,m) <- allPairs [0..] [0..] ]
To get a feel for how it works, draw an infinite quarter-plane, and look at the results of
take 100 $ allPairs [0..] [0..]
[2*n + 3*m +1 | m <- [0..], n <- [0..]] won't work because it starts with m = 0 and goes through all the n, and then has m = 1 and goes through all the n, etc. But just the m = 0 part is infinite, so you will never get to m = 1 or 2 or 3, etc. So [2*n + 3*m +1 | m <- [0..], n <- [0..]] is exactly the same as [2*n + 3*0 +1 | n <- [0..]].
To generate all of them, you either need to realize, like users vartec and Hynek -Pichi- Vychodil, that the set of numbers you want is just the natural numbers - {0,2}. Or you need to somehow enumerate all the pairs (m,n) such that m,n are nonnegative. One way to do that is to go along each of the "diagonals" where m + n is the same. So we start with the numbers where m + n = 0, and then the ones where m + n = 1, etc. Each of these diagonals has a finite number of pairs, so you will always go on to the next one, and all the pairs (m,n) will eventually be counted.
If we let i = m + n and j = m, then [(m, n) | m <- [0..], n <- [0..]] becomes [(j, i - j) | i <- [0..], j <- [0..i]]
So for you, you can just do
[2*(i-j) + 3*j +1 | i <- [0..], j <- [0..i]]
(Of course this method will also produce duplicates for you because there are multiple (m,n) pairs that generate the same number in your expression.)
my 0.2:
trans = concat [ f n | n <- [1..]]
where
mklst x = (\(a,b) -> a++b).unzip.(take x).repeat
f n | n `mod` 2 == 0 = r:(mklst n (u,l))
| otherwise = u:(mklst n (r,d))
u = \(a,b)->(a,b+1)
d = \(a,b)->(a,b-1)
l = \(a,b)->(a-1,b)
r = \(a,b)->(a+1,b)
mkpairs acc (f:fs) = acc':mkpairs acc' fs
where acc' = f acc
allpairs = (0,0):mkpairs (0,0) trans
result = [2*n + 3*m + 1 | (n,m) <- allpairs]
You can try enumerating all pairs of integers.
This code is based in the enumeration described at University of California Berkeley (doesn't include 0)
data Pair=Pair Int Int deriving Show
instance Enum Pair where
toEnum n=let l k=truncate (1/2 + sqrt(2.0*fromIntegral k-1))
m k=k-(l k-1)*(l k) `div` 2
in
Pair (m n) (1+(l n)-(m n))
fromEnum (Pair x y)=x+((x+y-1)*(x+y-2)) `div` 2
But you can use another enumeration.
Then you can do:
[2*n+3*m+1|Pair n m<-map toEnum [1..]]

Resources