Append integer to global list inside function haskell - list

I'll use a simple example for what I'm trying to do.
Say I have the list:
nums = []
Now I have the function:
allNums n = nums.append(n)
So if I run the function:
allNums 6
The list nums should have the values
[6]
I know nums.append doesn't work, but what code could replace that.

Simple Answer:
You can't do that. Haskell is a pure, functional language, that means:
A function does not have any side effect.
A function does always return the same result when called with the same parameters.
A function may or may not be called, but you don't have to care about that. If it wasn't called, it wasn't needed, but because the function does not have any side effects, you won't find out.
Complex answer:
You could use the State Monad to implement something that behaves a bit like this, but this is probably out of reach for you yet.

I'm suggesting to use an infinite list instead of appending to global variable.
It's true haskell is pure functional. But also it's lazy. Every part of data is not calculated until is really needed. It also applies to collections. So you could even define a collection with elements based on previous elements of same collection.
Consider following code:
isPrime n = all (\p -> (n `mod` p) /= 0 ) $ takeWhile (\p ->p * p <= n) primes
primes = 2 : ( filter isPrime $ iterate (+1) 3 )
main = putStrLn $ show $ take 100 primes
definition of isPrime is trivia when primes list is defined. It takes pack of primes which is less or equivalent to square root of examining number
takeWhile (\p ->p * p <= n) primes
then it checks if number have only non-zero remainders in division by all of these numbers
all (\p -> (n `mod` p) /= 0 )
the $ here is an application operator
Next using this definition we taking all numbers starting from 3:
iterate (+1) 3
And filtering primes from them.
filter isPrime
Then we just prepending the first prime to it:
primes = 2 : ( ... )
So primes becomes an infinite self-referred list.
You may ask: why we prepending 2 and just no starting filtering numbers from it like:
primes = filter isPrime $ iterate (+1) 2
You could check this leads to uncomputable expression because the isPrime function needs at least one known member of primes to apply the takeWhile to it.
As you can see primes is well defined and immutable while it could have as many elements as you'll need in your logic.

Related

Filtering lists which have the same number of different elements in them in Haskell

I am pretty new to Haskell and I have the data data Instruction = Add | Sub | Mul | Div | Dup | Pop deriving (Eq,Ord,Show,Generic) and I am generating lists with all possible combinations of Mul and Dup with mapM (const [Mul, Dup]) [1..n]) of size n.
I wanted only the lists starting with Dup and ending with Mul so I used filter((== Mul) . last)(filter((== Dup) . head) (mapM (const [Mul, Dup]) [1..n])) but I also want only the lists with the same number of Mul and Dup in them but I can't seem to come up with a way of doing this. How do I filter this and is there a more efficient way of doing this as there may be a huge amount of combinations as lists get bigger?
A sample list would look like this: [Dup,Mul,Dup,Mul] and [Dup,Dup,Mul,Mul] for lists of size 4.
While your approach is correct, I think it's not the most efficient one. You generate 2^N lists and then filter out many of them. Forgetting the other requirements to keep the counting simple, by requiring that we have as many Muls as Dups, we end up with only choose(N, N/2) lists (the number of subsets of size N/2 of 1..N), which is a much smaller figure.
We can instead try to avoid the filtering and generate the wanted lists, only, in the first place. I suggest the following approach, which you can modify as needed to satisfy the other requirements.
We define a function sameMulDup which takes two integers m and d and generates all the lists with m Muls and d Dups.
sameMulDup :: Int -> Int -> [[Instruction]]
sameMulDup 0 d = [replicate d Dup]
sameMulDup m 0 = [replicate d Mul]
sameMulDup m d = do
-- generate the first element
x <- [Dup, Mul]
-- compute how many m and d we have left
let (m', d') = case x of
Dup -> (m , d-1)
Mul -> (m-1, d )
-- generate the other elements
xs <- sameMulDup m' d'
return (x:xs)
Intuitively, if d=0 or m=0 there is only one possible list to include in out list-of-lists result. Otherwise, we non deterministically pick the first element, decrement the correponding counter d or m, and generate the rest.
Alternatively, the last equation can be replaced by the following more basic one:
sameMulDup m d =
map (Dup:) (sameMulDup m (d-1))
++
map (Mul:) (sameMulDup (m-1) d)
Anyway, given sameMuldup, you should be able to solve your full task.
It should be possible to define a function countPred :: a -> [a] -> Int, which counts the number of items in the list which are equal to the first argument; you can then do filter (\l -> countPred Mul l == countPred Dup l) (or alternately filter ((==) <$> countPred Mul <*> countPred Dup) if you prefer point-free form). Another approach I suppose might be to do (==0) . sum . map (\case { Mul -> 1, Dup -> (-1) }), but that strikes me as being slightly more complex than necessary.
I like chi's answer, but in a comment, I mentioned that it doesn't achieve as much sharing as it could. I speculated that the sharing would be beneficial if you iterate over the list of instructions multiple times, but worse if you iterate just once. Empirically, the sharing version appears to be faster no matter how many times you iterate, but the memory tradeoff is as predicted: worse for one iteration, better for multiple. So I thought it might be interesting to show it.
Here's how it looks. We're going to make an infinite list of answers. The first index will be how long the list of instructions will be; the second is how many Muls there are (though I'll use True and False instead of Mul and Dup). So:
bits :: [[[[Bool]]]]
bits = iterate extend [[[]]] where
extend bsss = zipWith (++)
(map (map (False:)) bsss ++ [[]])
([[]] ++ map (map (True:)) bsss)
For completeness, here's how you write a function with the same signature as chi's sameMulDup, and computing the same answer (up to the swap to Bool):
sameMulDup' :: Int -> Int -> [[Bool]]
sameMulDup' m d = bits !! (m+d) !! m
Some timings on my machine, for m=d=12, when compiled -O2:
sameMulDup , one iteration 1.35s 6480Kb
sameMulDup', one iteration 1.11s 226476Kb
sameMulDup , two iterations 4.26s 2135368Kb
sameMulDup', two iterations 1.97s 620880Kb
Here is the driver code I used for acquiring these numbers:
main :: IO ()
main = do
[sharing, twice, m, d] <- getArgs
let answer = (if read sharing then sameMulDup' else sameMulDup) (read m) (read d)
if read twice
then do
print . sum . map (sum . map fromEnum) $ answer
print . sum . map (sum . map (fromEnum . not)) $ answer
else print . sum . map (sum . map fromEnum) $ answer
There are some subtle points here:
To iterate over the list twice, we must have a way of referring to the same list in both iterations. This is answer in the above code.
We must use an iteration that actually forces all the values for it to be useful. I do this by counting up how many Trues there are, but there are other ways. (Just printing the whole list doesn't work well: the calculation's runtime is then dwarfed by the production of the String to print and the work done in transferring it to the terminal.)
Although the first iteration uses the same code in both branches of the if, it is important that this code not be shared and moved out of the if. We want the compiler to know in the else branch that answer will not be used again, so that it may garbage collect. If you write print answer >> if twice then print answer else pure (), it is not as obvious statically when the prefix of answer may be garbage collected.
In the then branch, I used two different calculations in the two loops, so that the compiler did not attempt to get clever and do the calculation just once and then print the calculated result twice.

Traversing a list until certain criterion is met

I would like to create a simple SML program that traverses a list from left to right.Let's say I have a list of N items of K different types.For example the list 1 3 1 3 1 3 3 2 2 1 has 10 numbers of 3(1,2,3) types.
What I would like to to is go through this list from left to right and stop when i have found all K different numbers.In this case I would stop right after stumbling upon the first 2.
This could be done by spliting the list in head and tail in each step and processing the head element.However how could I keep track of the different numbers I have found?
This could be done in C/C++ by simply holding a counter and a boolean array with K elements. If i stumble upon an element i with bool[i]=false i make it true and counter=counter+1.
It is stated though that arrays are not the best option for SML so i was wondering if i have to use another data structure or if i have to create a new function to check each time if i have seen this element before(this would cost in time complexity).
how could I keep track of the different numbers I have found?
[...] in C/C++ by [...] a boolean array with K elements
Abstractly I would call the data structure you want a bit set.
I'll give you two answers, one using a sparse container and one using a bit set.
Sparse
I'd use a list to keep track of the elements you've already seen:
fun curry f x y = f (x, y)
val empty = []
fun add x set = curry op:: x set
fun elem x set = List.exists (curry op= x) set
fun seen k xs =
let fun seen_ 0 _ _ = true
| seen_ _ [] _ = false
| seen_ k (x::xs) set =
if elem x set
then seen_ k xs set
else seen_ (k-1) xs (add x set)
in seen_ k xs empty end
You could also use a balanced binary tree as set type; this would reduce lookup to O(lg n). The advantage of using an actual container (list or tree) rather than a bit array is that of sparse arrays/matrices. This works for ''a lists.
Bit set
[...] boolean array with K elements [...]
If i stumble upon an element i [...]
Until this point, you haven't said that elements are always unsigned integers from 0 to K-1, which would be a requirement if they should be representable by a unique index in an array of length K.
SML has a module/type called Word / word for unsigned integers (words). Adding this constraint, the input list should have type word list rather than ''a list.
When you make an array of primitive types in many imperative, compiled languages, you get mutable, unboxed arrays. SML's Array type is also mutable, but each bool in such an array would be boxed.
An easy way to get an immutable, unboxed array of bits would be to use bitwise operations on an IntInf (SML/NJ; implementations vary); it would automatically grow as a bit is flipped. This could look like:
fun bit x = IntInf.<< (1, x)
val empty = IntInf.fromInt 0
fun add x set = IntInf.orb (set, bit x)
fun elem x set = IntInf.> (IntInf.andb (set, bit x), 0)
The function seen would be the same.
The fact that k is decreased recursively and that set grows dynamically means that you're not restricted to elements in the range [0,K-1], which would have been the case with an array of size K.
Example use:
- seen 5 [0w4, 0w2, 0w1, 0w9];
val it = false : bool
- seen 5 [0w1, 0w2, 0w3, 0w4, 0w8];
val it = true : bool
This solution uses a lot of memory if the elements are large:
- seen 1 [0w100000000];
*eats my memory slowly*
val it = true : bool
Additional things you could do:
Create a module, structure BitSet = struct ... end that encapsulates an abstract type with the operations empty, add and elem, hiding the particular implementation (whether it's an IntInf.int, or a bool Array.array or an ''a list).
Create a function, fun fold_until f e xs = ... that extracts the recursion scheme of seen_ so that you avoid manual recursion; a regular foldl is not enough since it continues until the list is empty. You could build this using error-aware return type or using exceptions.
Consider Bloom filters.

Haskell - Finding Divisors of an Integer

According to the book this is how its done, but I am not able to get this to work. It gives me an error Not in scope: 'ld'. I'm guessing I should be importing some package but not sure which one. Also the book uses GS module at the prompt but I'm using WinGHCi that has Prelude. What am I missing here?
factors :: Int -> [Int]
factors n | n < 1 = error "not positive"
| n == 1 = []
| otherwise = p : factors (div n p)
where p = ld n
I guess this can also be done using map and filter functions? How?
I suppose the aim of the assignment is to teach you about list comprehensions, filter and similar constructs, and not to have you write functions that test for primality or create the list of divisors in any sensible way. Therefore what you need is a predicate divides,
divides :: Int -> Int -> Bool
a `divides` b = ???
Then you use that predicate for the argument to filter or in a list comprehension to find the list of divisors, and use the divisors function for your isPrime test.
You want to inspect all numbers from 1 to n, and keep them only if they divide n. The filter function can help you:
divisors n = filter ??? [1..n]
So what condition you need to put in place of ??? ?
For the isPrime function you could reuse the divisors function, you already mentioned how.
Break it down into simpler steps.
Write a function, divides :: Int -> Int -> Bool such that
x `divides` n
is true when x is a divisor of n. So, first, think about what it means for x to be a divisor of n.
Now that you have a way to check if a single number x is a divisor of n, you need to check a certain range of numbers less than n to see which ones are divisors.
Hint: In Haskell, you can generate a list of numbers from 1 to n like so: [1..n]
This is where that filter function you mention would be useful. Check its type:
filter :: (a -> Bool) -> [a] -> [a]
Just replace the a above with Int.
As far as the isPrime function, just think about what it means for a number to be prime... if you've calculated your divisors correctly, you can check the list to make sure that it matches with that property.
If this is a homework related question, you should definitely tag it with homework, then people don't feel as timid about helping out :)

haskell, counting how many prime numbers are there in a list

i m a newbie to haskell, currently i need a function 'f' which, given two integers, returns the number of prime numbers in between them (i.e., greater than the first integer but smaller than the second).
Main> f 2 4
1
Main> f 2 10
3
here is my code so far, but it dosent work. any suggestions? thanks..
f :: Int -> Int -> Int
f x y
| x < y = length [ n | n <- [x..y], y 'mod' n == 0]
| otherwise = 0
Judging from your example, you want the number of primes in the open interval (x,y), which in Haskell is denoted [x+1 .. y-1].
Your primality testing is flawed; you're testing for factors of y.
To use a function name as an infix operator, use backticks (`), not single quotes (').
Try this instead:
-- note: no need for the otherwise, since [x..y] == [] if x>y
nPrimes a b = length $ filter isPrime [a+1 .. b-1]
Exercise for the reader: implement isPrime. Note that it only takes one argument.
Look at what your list comprehension does.
n <- [x..y]
Draw n from a list ranging from x to y.
y `mod` n == 0
Only select those n which evenly divide y.
length (...)
Find how many such n there are.
What your code currently does is find out how many of the numbers between x and y (inclusive) are factors of y. So if you do f 2 4, the list will be [2, 4] (the numbers that evenly divide 4), and the length of that is 2. If you do f 2 10, the list will be `[2, 5, 10] (the numbers that evenly divide 10), and the length of that is 3.
It is important to try to understand for yourself why your code doesn't work. In this case, it's simply the wrong algorithm. For algorithms that find whether a number is prime, among many other sources, you can check the wikipedia article: Primality test.
I you want to work with large intervals, then it might be a better idea to compute a list of primes once (instead of doing a isPrime test for every number):
primes = -- A list with all prime numbers
candidates = [a+1 .. b-1]
myprimes = intersectSortedLists candidates primes
nPrimes = length $ myprimes

Intermediate lists in Haskell

I am doing Project Euler question 55 on Lychrel numbers where the aim is to find the number of Lychrel numbers below 10,000 within 50 iterations. I came up with this:
revAdd n = (read $ reverse $ show n) + n
lychrel n | length xs == 50 = error "False"
| ((reverse $ show (revAdd n)) == (show (revAdd n))) = True
| otherwise = (lychrel (revadd n) ) : xs
answer = length [ x | x <- [1..10000] , lychrel x == True]
But I don't know how to define xs as the list of previous iterations upon n, which are when n is not a palindrome. How would I do this, and secondly would this work?
It becomes much easier if you separate your concerns into distinct steps.
Define a function that sums a number and its reverse.
Use iterate to repeat your number, starting from x.
Use take to limit your iteration to 50 steps.
Use all with a predicate to determine if any of these steps results in a palindrome.
You need to pass the list of iterations (or just the number of iterations) in as a parameter to lychrel, starting with [] in the call from answer and adding to it in the recursive call in the otherwise case. Look up "accumulating parameters" for more general background on this technique.