I'm trying to trim a list of random numbers so that sum of the numbers in [0,1] in the resulting smaller list accumultates to a value under 1.
This is interesting in a sense that average of these list prefix lengths is e, somehow.
While getting the length of prefix I encountered a problem - I managed to get the program to work on a determined infinite list, or a slice of random list, but the program hangs on infinite random list. What am I doing wrong?
import System.Random
-- Count list items that accumulate to 1.
count :: (Num a, Ord a) => [a] -> Int
count xs = 1 + length xs'
where xs'= takeWhile (< 1) $ scanl1 (+) xs
-- Works of infinite list
a = (return (repeat 0.015)) :: IO [Double]
fa = fmap count a
--67
-- Works on trimmed list of randoms
rio = randomRIO (0::Double, 1)
b = sequence $ take 10 (repeat rio)
fb = fmap count b
-- fb is usually 2 to 5
-- Hangs on infinite list of randoms
c = sequence (repeat rio)
fc = fmap count c
-- fc hangs... ;(
You can define an IO action to create an infinite stream of ranged random numbers like so:
import System.Random
randomRIOs :: (Random a) => (a, a) -> IO [a]
randomRIOs (a, b) = randomRs (a, b) <$> newStdGen
After which, the following works fine with your definition of count:
main = do
n <- count <$> randomRIOs (0::Double, 1)
print n
You can't really have an infinite list of random numbers, because randomness is too strict. So, you can't have the call to sequence outside of your call to count. One obvious thing you could try would be a partial reimplementation of sequence inside of count itself:
count :: (Num a, Ord a, Monad m) => [m a] -> m (Maybe Int)
count = go 0 0
where go n total [] = pure Nothing
go n total (x:xs) = do
num <- x
let total' = total + num
n' = succ n
if total' >= 1
then pure $ Just n'
else go n' total' xs
I've also amended the result to return a Maybe, because it seems wrong to return 1 for an empty list (as yours did), or return the length of a list even if its elements sum to something less than 1.
Another reasonable change would be to not accept [m a], but just a single m a, which can reliably produce a value any number of times. Then we don't have to worry about the input running out, and so no Maybe is needed:
count :: (Num a, Ord a, Monad m) => m a -> m Int
count m = go 0 0
where go n total = do
num <- m
let total' = total + num
n' = succ n
if total' >= 1
then pure n'
else go n' total'
Then you can simply call count $ randomRIO (0::Double, 1), and it will produce as many random numbers as are needed.
Related
I can't use patterns or folding, per the parameters of the assignment, of which this is a toy example of a particular approach to a larger problem.
When I run the code, I get a '0', naturally. So the question is, how do I get the final value of a_count?
fun num_counter(numbers: int list, a_number: int) =
let val count = 0
in
let fun count_num(numbers: int list, a_count: int) =
if null numbers
then 0
else if (hd numbers) = a_number
then count_num(tl numbers, count + 1)
else count_num(tl numbers, count)
in
count
end
end
There are several issues with your code:
Your recursive function count_num is never called.
Your recursion terminates by returning 0 instead of the result
you've acumulated so far (a_count).
There is some confusion between parameter a_count that, as I
understood holds the number of occurences of a_number and count
declared at the second line.
Here is some correction to it:
fun num_counter(numbers: int list, a_number: int) = let
fun count_num(numbers: int list, count: int) =
if null numbers
then count (* reached the end of the list =>
returned the number of occurences computed *)
else if (hd numbers) = a_number
then count_num(tl numbers, count + 1)
else count_num(tl numbers, count)
in
count_num (numbers, 0) (* first call of count_num,
count initiated to 0 *)
end;
Also note that you can use pattern matching to enhance readability of
your recursive function:
fun num_counter(numbers: int list, a_number: int) =
let fun count_num([], count) = count
| count_num(i :: tl, count) =
count_num(tl, if i = a_number then count + 1 else count)
in
count_num (numbers, 0)
end;
You can write it shorter using a fold:
fun num_counter (numbers, a_number) =
let fun count (b_number, total) =
if a_number = b_number
then total + 1
else total
in foldl count 0 numbers
end
Here foldl takes three arguments: the function count that accumulates the result when visiting each number, b_number in numbers, the initial value for total being 0 and the numbers to fold over, numbers. When foldl has visited the last number, it uses the last accumulation in total as the result.
foldl is itself defined like this:
fun foldl f e [] = e
| foldl f e (x::xr) = foldl f (f(x, e)) xr
Or you can filter and take the length which costs a bit more:
fun num_counter (numbers, a_number) =
length (filter (fn b_number => a_number = b_number) numbers)
I am writing a code in Haskell which take a list of 0's and 1's like [1,1,0,0,1,0,1] return a Pair(tuple) of the number occurrence of 0 and 1 in a list like (3,4).
Here is my code:
inc :: Int -> Int
inc x = (\x -> x + 1) x
count :: [Int] -> (Int,Int)
c = (0,0)
count x =
if null x
then c
else if head x == 0
then do
inc (fst c)
count (tail x)
else if head x == 1
then do
inc (snd c)
count (tail x)
I have also tried doing it in a guarded form:
count :: [Int] -> (Int,Int)
c = (0,0)
count x
| null x = c
| head x == 0 = inc (fst c) >> count (tail x)
| head x == 1 = inc (snd c) >> count (tail x)
The main problem is that I am not sure how to implement two function in one then statement.
You're thinking all imperatively. Something like do { inc (fst c); count (tail x) } would only make sense if c was some kind of mutable state variable. Haskell variables are not mutable, so inc can't modify the fst of c, it can only give you a modified copy. This might become clearer if you rewrite inc to the completely equivalent simpler form:
inc x = x + 1
(In fact, inc = (+1) would also do.)
Now, in count, you're trying to carry on and increment a single accumulator variable through the recursion loop. You can do that, but you need to be explicit about passing the modified version to the recursive call:
count = go (0,0)
where go :: (Int,Int) -> [Int] -> (Int,Int)
go c x
| null x = c
| head x == 0 = go (first inc c) (tail x)
| head x == 1 = go (second inc c) (tail x)
This pattern of defining a small local helper function (go is just an arbitrary name, I could have also called it getTheCountingDone) and using it as the “loop body” of the recursion is quite common in Haskell. Basically go (0,0) “initialises” c to the value (0,0), then starts the first loop iteration. For the second iteration, you recurse to e.g. go (first inc c), i.e. you start the loop again with the updated c variable.
I've used first and second for incrementing the respective tuple field. fst only reads the first field, i.e. gives you its value, whereas first makes a tuple-update function from an element-update function. Instead of import Control.Arrow you could also define this yourself:
first :: (a->b) -> (a,y) -> (b,y)
first f (a, y) = (f a, y)
second :: (a->b) -> (x,a) -> (x,b)
second f (x, a) = (x, f a)
(The Control.Arrow version is actually more general, but you don't need to worry about that – you can use it in just the same way.)
Note that deconstructing lists with head and tail is heavily eschewed in Haskell: it's easy to get wrong – you may forget to check the list is nonempty before accessing an element, which will throw a nasty runtime error. Better use pattern matching:
count = go (0,0)
where go c [] = c
go c (0:xs) = go (first inc c) xs
go c (1:xs) = go (second inc c) xs
Actually this is still not safe: you don't have exhaustive cases; the function fails if the list contains anything but zeroes or ones. Perhaps you'd like to count all zero and nonzero elements?
count = go (0,0)
where go c [] = c
go c (0:xs) = go (first inc c) xs
go c (_:xs) = go (second inc c) xs
another alternative
> import Data.List(group,sort)
> count = tuplify . map length . group . sort
where tuplify [x,y] = (x,y)
One solution would be to filter the list twice, once keeping the zeroes, and once keeping the ones:
count :: [Int] -> (Int, Int)
count nums = (length (filter (0 ==) nums), length (filter (1 ==) nums))
One option would be to have a second parameter for your count function which keeps track of what you have already counted:
count :: [Int] -> (Int, Int) -> (Int, Int)
-- if the list is empty, return the ones and zeroes already counted
count [] (zeroes, ones) = (zeroes, ones)
-- if first element is a 0, increment the existing count for zeroes
-- and count the rest
count (0:more) (zeroes, ones) = count more (zeroes + 1, ones)
-- as before, but the first element is a 1
count (1:more) (zeroes, ones) = count more (zeroes, ones + 1)
When we call count, we have to give it a 'starting count' of (0,0):
count [1,0,1,1,1,0,0,1] (0,0)
which returns (3,5) as the first 0 in the initial pair is incremented 3 times by the zeroes in the list, and the second 0 in the initial pair is incremented 5 times by the ones in the list.
This solution is a common functional programming style called 'accumulating parameter'.
Hi i'm pretty new to haskell and I want to make a program with prime numbers.
With the code below I put all the prime numbers between 2 integers in a list, now i want to make a sum of all the prime numbers of the generated list and show this as an answer.
primesR :: Integral a => a -> a -> [a]
primesR a b = takeWhile (<= b) $ dropWhile (< a) $ sieve [2..]
where sieve (n:ns) = n:sieve [ m | m <- ns, m `mod` n /= 0 ]
I didn't find any examples of the sum of a generated list. Does anyone know how I can manage this in the code?
thx
Just use the sum function, like so:
primesR :: Integral a => a -> a -> a
primesR a b = sum $ takeWhile (<= b) $ dropWhile (< a) $ sieve [2..]
where sieve (n:ns) = n:sieve [ m | m <- ns, m `mod` n /= 0 ]
Note that you need to change the function signature from Integral a => a -> a -> [a] to Integral a => a -> a -> a, since the result of summation is a single value, not a list.
I have a simple function (used for some problems of project Euler, in fact). It turns a list of digits into a decimal number.
fromDigits :: [Int] -> Integer
fromDigits [x] = toInteger x
fromDigits (x:xs) = (toInteger x) * 10 ^ length xs + fromDigits xs
I realized that the type [Int] is not ideal. fromDigits should be able to take other inputs like e.g. sequences, maybe even foldables ...
My first idea was to replace the above code with sort of a "fold with state". What is the correct (= minimal) Haskell-category for the above function?
First, folding is already about carrying some state around. Foldable is precisely what you're looking for, there is no need for State or other monads.
Second, it'd be more natural to have the base case defined on empty lists and then the case for non-empty lists. The way it is now, the function is undefined on empty lists (while it'd be perfectly valid). And notice that [x] is just a shorthand for x : [].
In the current form the function would be almost expressible using foldr. However within foldl the list or its parts aren't available, so you can't compute length xs. (Computing length xs at every step also makes the whole function unnecessarily O(n^2).) But this can be easily avoided, if you re-thing the procedure to consume the list the other way around. The new structure of the function could look like this:
fromDigits' :: [Int] -> Integer
fromDigits' = f 0
where
f s [] = s
f s (x:xs) = f (s + ...) xs
After that, try using foldl to express f and finally replace it with Foldable.foldl.
You should avoid the use of length and write your function using foldl (or foldl'):
fromDigits :: [Int] -> Integer
fromDigits ds = foldl (\s d -> s*10 + (fromIntegral d)) 0 ds
From this a generalization to any Foldable should be clear.
A better way to solve this is to build up a list of your powers of 10. This is quite simple using iterate:
powersOf :: Num a => a -> [a]
powersOf n = iterate (*n) 1
Then you just need to multiply these powers of 10 by their respective values in the list of digits. This is easily accomplished with zipWith (*), but you have to make sure it's in the right order first. This basically just means that you should re-order your digits so that they're in descending order of magnitude instead of ascending:
zipWith (*) (powersOf 10) $ reverse xs
But we want it to return an Integer, not Int, so let's through a map fromIntegral in there
zipWith (*) (powersOf 10) $ map fromIntegral $ reverse xs
And all that's left is to sum them up
fromDigits :: [Int] -> Integer
fromDigits xs = sum $ zipWith (*) (powersOf 10) $ map fromIntegral $ reverse xs
Or for the point-free fans
fromDigits = sum . zipWith (*) (powersOf 10) . map fromIntegral . reverse
Now, you can also use a fold, which is basically just a pure for loop where the function is your loop body, the initial value is, well, the initial state, and the list you provide it is the values you're looping over. In this case, your state is a sum and what power you're on. We could make our own data type to represent this, or we could just use a tuple with the first element being the current total and the second element being the current power:
fromDigits xs = fst $ foldr go (0, 1) xs
where
go digit (s, power) = (s + digit * power, power * 10)
This is roughly equivalent to the Python code
def fromDigits(digits):
def go(digit, acc):
s, power = acc
return (s + digit * power, power * 10)
state = (0, 1)
for digit in digits:
state = go(digit, state)
return state[0]
Such a simple function can carry all its state in its bare arguments. Carry around an accumulator argument, and the operation becomes trivial.
fromDigits :: [Int] -> Integer
fromDigits xs = fromDigitsA xs 0 # 0 is the current accumulator value
fromDigitsA [] acc = acc
fromDigitsA (x:xs) acc = fromDigitsA xs (acc * 10 + toInteger x)
If you're really determined to use a right fold for this, you can combine calculating length xs with the calculation like this (taking the liberty of defining fromDigits [] = 0):
fromDigits xn = let (x, _) = fromDigits' xn in x where
fromDigits' [] = (0, 0)
fromDigits' (x:xn) = (toInteger x * 10 ^ l + y, l + 1) where
(y, l) = fromDigits' xn
Now it should be obvious that this is equivalent to
fromDigits xn = fst $ foldr (\ x (y, l) -> (toInteger x * 10^l + y, l + 1)) (0, 0) xn
The pattern of adding an extra component or result to your accumulator, and discarding it once the fold returns, is a very general one when you're re-writing recursive functions using folds.
Having said that, a foldr with a function that is always strict in its second parameter is a really, really bad idea (excessive stack usage, maybe a stack overflow on long lists) and you really should write fromDigits as a foldl as some of the other answers have suggested.
If you want to "fold with state", probably Traversable is the abstraction you're looking for. One of the methods defined in Traversable class is
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
Basically, traverse takes a "stateful function" of type a -> f b and applies it to every function in the container t a, resulting in a container f (t b). Here, f can be State, and you can use traverse with function of type Int -> State Integer (). It would build an useless data structure (list of units in your case), but you can just discard it. Here's a solution to your problem using Traversable:
import Control.Monad.State
import Data.Traversable
sumDigits :: Traversable t => t Int -> Integer
sumDigits cont = snd $ runState (traverse action cont) 0
where action x = modify ((+ (fromIntegral x)) . (* 10))
test1 = sumDigits [1, 4, 5, 6]
However, if you really don't like building discarded data structure, you can just use Foldable with somewhat tricky Monoid implementation: store not only computed result, but also 10^n, where n is count of digits converted to this value. This additional information gives you an ability to combine two values:
import Data.Foldable
import Data.Monoid
data Digits = Digits
{ value :: Integer
, power :: Integer
}
instance Monoid Digits where
mempty = Digits 0 1
(Digits d1 p1) `mappend` (Digits d2 p2) =
Digits (d1 * p2 + d2) (p1 * p2)
sumDigitsF :: Foldable f => f Int -> Integer
sumDigitsF cont = value $ foldMap (\x -> Digits (fromIntegral x) 10) cont
test2 = sumDigitsF [0, 4, 5, 0, 3]
I'd stick with first implementation. Although it builds unnecessary data structure, it's shorter and simpler to understand (as far as a reader understands Traversable).
Create an infinite list pairs :: [(Integer, Integer)] containing pairs of the form (m,n),
where each of m and n is a member of [0 ..]. An additional requirement is that if (m,n)
is a legit member of the list, then (elem (m,n) pairs) should return True in finite time.
An implementation of pairs that violates this requirement is considered a non- solution.
****Fresh edit Thank you for the comments, Lets see if I can make some progress****
pairs :: [(Integer, Integer)]
pairs = [(m,n) | t <- [0..], m <- [0..], n <-[0..], m+n == t]
Something like this? I just don't know where it's going to return True in finite time.
I feel the way the question is worded elem doesn't have to be part of my answer. Just if you call (elem (m,n) pairs) it should return true. Sound right?
Ignoring the helper method, the list comprehension you have will list out all pairs but the order of elements is a problem. You'll have a infinitely many pairs like (0, m) which are followed by infinitely many pairs like (1, m). Of course elem will forever iterate all the (0, m) pairs never reaching (1, m) or (2, m) etc.
I'm not sure why you have the helper method -- with it, you are only building a list of pairs like [(0,0), (1,1), (2,2), ...] because you've filtered on m = n. Was that part of the requirements?
Like #hammar suggested, start with 0 = m + n and list out the pairs (m, n). Then list pairs (m, n) where 1 = m + n. Then your list will look like [(0,0), (0,1), (1,0), (0,2), (1,1), (2,0), ...].
The helper function ensures that pairs is a list of the form [ (0,0) , (1,1) , (2,2) ... ].
So elem ( m , n ) pairs can be implemented as:
elem (m , n) _ | m == n = True
| otherwise = False
This is a constant time implementation.
I first posted
Prelude> let pairs = [(m, n) | t <- [0..]
, let m = head $ take 1 $ drop t [0..]
, let n = head $ take 1 $ drop (t + 1) [0..]]
Which, I believed answered the three conditions set by the professor. But hammar pointed out that if I chose this list as an answer, that is, the list of pairs of the form (t, t+1), then I might as well choose the list
repeat [(0,0)]
Well, both of these do seem to answer the professor's question, considering there seems to be no mention of the list having to contain all combinations of [0..] and [0..].
That aside, hammer helped me see how you can list all combinations, facilitating the evaluation of elem in finite time by building the infinite list from finite lists. Here are two other finite lists - less succinct than Hammar's suggestion of the diagonals - that seem to build all combinations of [0..] and [0..]:
edges = concat [concat [[(m,n),(n,m)] | let m = t, n <- take m [0..]] ++ [(t,t)]
| t <- [0..]]
*Main> take 9 edges
[(0,0),(1,0),(0,1),(1,1),(2,0),(0,2),(2,1),(1,2),(2,2)]
which construct the edges (t, 0..t) (0..t, t), and
oddSpirals size = concat [spiral m size' | m <- n] where
size' = if size < 3 then 3 else if even size then size - 1 else size
n = map (\y -> (fst y * size' + div size' 2, snd y * size' + div size' 2))
[(x, t-x) | let size' = 5, t <- [0..], x <- [0..t]]
spiral seed size = spiral' (size - 1) "-" 1 [seed]
spiral' limit op count result
| count == limit =
let op' = if op == "-" then (-) else (+)
m = foldl (\a b -> a ++ [(op' (fst $ last a) b, snd $ last a)]) result (replicate count 1)
nextOp = if op == "-" then "+" else "-"
nextOp' = if op == "-" then (+) else (-)
n = foldl (\a b -> a ++ [(fst $ last a, nextOp' (snd $ last a) b)]) m (replicate count 1)
n' = foldl (\a b -> a ++ [(nextOp' (fst $ last a) b, snd $ last a)]) n (replicate count 1)
in n'
| otherwise =
let op' = if op == "-" then (-) else (+)
m = foldl (\a b -> a ++ [(op' (fst $ last a) b, snd $ last a)]) result (replicate count 1)
nextOp = if op == "-" then "+" else "-"
nextOp' = if op == "-" then (+) else (-)
n = foldl (\a b -> a ++ [(fst $ last a, nextOp' (snd $ last a) b)]) m (replicate count 1)
in spiral' limit nextOp (count + 1) n
*Main> take 9 $ oddSpirals 3
[(1,1),(0,1),(0,2),(1,2),(2,2),(2,1),(2,0),(1,0),(0,0)]
which build clockwise spirals of length 'size' squared, superimposed on hammar's diagonals algorithm.
I believe the solution to your task is:
pairs = [(x,y) | u <- [0..], x <- [0..u], y <-[0..u] , u == x+y]