Haskell Division of all elements of a list - list

I have a problem with this function, that should divide all elements of a list.
[x1,x2,x3,x4,x5,x6] = (((((x1/x2)/x3)/x4)/x5)/x6)
My code thus far is:
division :: [Double] -> Double
divis :: [Double] -> Double
divis [] = 0
divis [x] = x
divis (x1:xs) = ????
How could I solve this problem?

so i found 2 sollutions. thx to Alec and Mark Seemann
divis :: [Double] -> Double
divis [x] = x
divis (x1 : xs) = x1 / mul xs
and
div2 :: [Double] -> Double
div2 (x1:xs) = foldl (/) x1

Related

A function that returns the highest average from multiple lists of numbers

I have to define a highestAverage :: [[Int]] -> Double function that returns the highest average from a list of lists containing numbers.
For example:
bestAverage [[3,1], [5,4,3], [], [5,5,5], [1,2,3]] == 5.0
I have already written a function that returns the average of a list.
listAverage :: [Int] -> Double
listAverage [] = 0.0
listAverage x = fromIntegral(sum x)/fromIntegral(length x)
My problem is that I can't figure out a way to have it do recursion. I always get errors when loading in my module.
My code right now looks like this:
highestAverage :: [[Int]] -> Double
highestAverage [[]] = 0.0
highestAverage (x:xs) = max(listAverage x, listAverage xs)
For a non-empty list you call the groupAvg on the first sublist x, and then determine the max between that value, and the recursive call on the tail of the list. The base case is a single sublist where we calculate the maxiumum:
highestAverage :: [[Int]] -> Double
highestAverage [x] = listAverage x
highestAverage (x:xs) = max (listAverage x) (highestAverage xs)
This function will not work for an empty list. If you want to return 0 for an empty list, you can alter the base case to:
highestAverage :: [[Int]] -> Double
highestAverage [] = 0
highestAverage (x:xs) = max (listAverage x) (highestAverage xs)
You can simply map your function over the list and take the maximum:
maximum $ map listAverage [[3,1], [5,4,3], [], [5,5,5], [1,2,3]]

Adding a list of points together

How do I add all of the x coordinates together in a list of points type Pt?
Example:
[Pt 1 2, Pt 3 4] => 1 + 3 => 4
Here is the data-type and function declaration that I am using:
data Point = Pt Double Double
x :: [Point] -> Point
This is what I have tried.
x :: [Point] -> Point
x [Pt x y] = Pt(x+x)
Probably the easiest way to do this, is by first making a function that can extract the x-coordinate of a point. For example with xPt:
xPt :: Point -> Double
xPt (Pt x _) = x
then we can make use of sum :: (Foldable f, Num a) => f a -> a and map :: (a -> b) -> [a] -> [b] to map a list of points to a list of x-coordinates:
xSum :: [Point] -> Double
xSum = sum . map xPt
You can use a list comprehension for this:
xSum :: [Point] -> Double
xSum pts = sum [x | Pt x _ <- pts]

Haskell - an infinite List which is divisible by every number of a given List

I am still a beginner in Haskell and currently I am trying to create a function in which i generate an infinite list from which I (if I use take 10 for example) take the first ten number, which are divisible by another list, which is given.
Here is my idea:
myCode :: [Int] -> [Int]
myCode (a:as) = [ x | x <- [0..] , x `mod` a == 0 , x `mod` myCode as ==0]
As you may have notices is that I am trying to solve it through recursion, however I always get the error "Couldn't match expected type ‘Bool’ with actual type ‘[Int]’ "
I am kinda at a loss, because I wouldn't know how else to solve this particular problem.
No need to use recursion here: simply use all (or any) as condition:
alldiv :: [Int] -> Int -> Bool
alldiv l b = all (\n -> b `mod` n == 0) l
myCode :: [Int] -> [Int]
myCode as = [ x | x <- [0..] , alldiv as x]
You can rewrite alldiv to:
alldiv :: [Int] -> Int -> Bool
alldiv l b = all ((==) 0 . mod b) l
or even attach it locally to myCode:
myCode :: [Int] -> [Int]
myCode as = [ x | x <- [0..] , alldiv x]
where alldiv b = all ((==) 0 . mod b) as
Finally you do not need list comprehension, you can simply use filter:
myCode :: [Int] -> [Int]
myCode as = filter alldiv [0..]
where alldiv b = all ((==) 0 . mod b) as
EDIT
Since it is sufficient that it one element in the list is a divider, you only need to replace all with any.

Repeatedly call a function: Haskell

Basically, I want to create a function that takes a list of integers and another list (this list can be of any type) and produce another list that has the elements in it from the "other list" at intervals specified by the list of integers. If I input:
ixs [2,3,1] [3,2,1]
[2,1,3]
So far I have:
ix :: Int -> [a] -> a
ix a [] = error "Empty list"
ix 1 (x:xs) = x
ix a (x:xs) = ix (a-1) xs
ixs :: [Int] -> [a] -> [a]
ixs [] _ = []
ixs _ [] = []
ixs (x:xs) (y) = ix x y: []
With this code I only get one value returned like so:
ixs [1,2] [2,1]
[2]
How can I call the ix function repeatedly on (x:xs) so that it returns all the values I want?
Edit: I want to do this without using any standard prelude functions. I just want to use recursion.
This is (almost) a map of an indexing ("getting the value at") of the first list over the second list
import Data.List ((!!))
-- (!!) :: [a] -> Int -> a
ixs :: [Int] -> [b] -> [b]
ixs ary ixes = map (ary !!) ixes
But you also have wraparound when you index a 3-element list by (3 mod 3 = 0), so we ought to just map mod over the indexes
ixs ary ixes = map (ary !!) (map (`mod` length ary) ixes)
And then we can simplify to "pointless style"
ixs ary = map (ary !!) . map (`mod` length ary)
which reads nicely as "map the indices modulo the array length then map the array indexing over the resultant indices". And it gives the right result
> ixs [2,3,1] [3,2,1]
[2,1,3]
To break down the Prelude function and Data.List function, we have
(!!) :: [b] -> Int -> b
(x:_) !! 0 = x
(_:xs) !! n
| n > 0 = xs !! (n-1)
| otherwise = error "List.(!!): negative argument."
_ !! _ = error "List.(!!): index too large."
and
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
You could reverse the order of the arguments
ix' :: [a] -> Int -> a
ix' [] a = error "Empty list"
ix' (x:xs) 1 = x
ix' (x:xs) a = ix' xs (a-1)
to make it easier to map ix over a list of indeces:
ixs' :: [a] -> [Int] -> [a]
ixs' xs is = map (ix' xs) is
Like this:
> ixs' "Hello Mum" [1,5,6,1,5,6,1,5]
"Ho Ho Ho"
but it would be nicer to use flip to swap the arguments - ix' is just flip ix, so you could do
ixs :: [Int] -> [a] -> [a]
ixs is xs = map (flip ix xs) is
which you then call the way round you'd planned:
> ixs [1,5,6,1,5,6,1,5] "Hello Mum"
"Ho Ho Ho"
Perhaps something like this
ixs :: [Int] -> [a] -> [a]
ixs idx a = map (`ix` a) idx
What you want to do is map your index function across all the values in the list of
indices to index the second list. Note that your ix function is just !! function, but starts indexing from 1 instead of 0.

Extending a list of list in Haskell

Is there anyway that I can extend a list of list in Haskell?
I'm trying to write a function that generates [1,2,2,3,3,3,4,4,4,4.....] which is basically a 1 one, 2 twos, 3 threes etc.
My Attempt:
nnss :: [Integer]
nnss = [nPrint x x | x <- [1,2..]]
The problem with my attempt is that nPrint x x returns a list of integers, for example, nPrint 2 2 would return [2, 2]. Is there anyway I can "expand" the list from [1,2,3...] to [1,2,2,3,3,3...] ?
The function signature we're looking for is [[a]] -> [a] and if we check hoogle we see that concat is what we're looking for.
And in this case though, the list comprehension is unnecessary since we're just iterating over each item, so we really want to just do a map. So since combining map and concat is so common we can just write
concatMap (\x -> nPrint x x) [1..]
You can ignore this if you're new to haskell but since the list monad is defined with concatMap we could also write
[1..] >>= \x -> nPrint x x
You can also write it without using maps and list concatenations (just prepend in constant time):
nnss :: [Integer]
nnss = genRepeated 1 1
genRepeated :: Integer -> Integer -> [Integer]
genRepeated x 0 = genRepeated (x+1) (x+1)
genRepeated x y = x : genRepeated x (y-1)
Than
take 22 nnss == [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6,6,6,7]
Other fast possibility is:
nnss :: [Integer]
nnss = flatten [take x $ repeat x | x <- [1..]]
flatten :: [[a]] -> [a]
flatten [] = []
flatten ([]:xs) = flatten xs
flatten ((x:xs):ys) = x : flatten (xs:ys)
Just add concat:
nnss :: [Integer]
nnss = concat [nPrint x x | x <- [1,2..]]