Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Need to implement a split with foldl or foldr.
For example: split [2, 4, 6, 8, 7] into ([2, 6, 7], [4, 8]).
This is relatively straight-forward. We know the type of our "seed" for the fold, it must be a pair of lists. We alternate which list of the two lists we're appending to by simply swapping the two lists, and we append to list on the left (which will change between each iteration).
foldr (\x (ys,zs) -> (x:zs, ys)) ([],[]) [2,4,6,8,7] -- ([2,6,7],[4,8])
If we were to use foldl the lists would come out backwards, so foldr seems like the logical choice.
Given a predicate p :: a -> Bool you can split on that using foldr as follows:
split :: (a -> Bool) -> [a] -> ([a],[a])
split p = foldr (\x (as, bs) -> if p x then (x:as, bs) else (as, x:bs)) ([],[])
For example:
Prelude> split (\x -> x `mod` 4 /= 0) [2,4,6,8,7]
([2,6,7],[4,8])
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have to implement a(n) [a -> b] -> [a] -> [b] function that has to run the given functions on the second list's respective elements.
For example:
functionList [\x->x+2] [2] == [4]
functionList [\x->x+2, \x->x-2, \x->x*2] [2,3,6] == [4,1,12]
So far, I have this:
functionList f xs = [ f x | x <- f ]
which returns a type matching error I don't know what to do with.
You can use zip :: [a] -> [b] -> [(a,b)] to simplify the problem. If you wanted to use it directly that'd probably look like a = (map (uncurry ($))) . zip, but zipWith is a normal shortcut that you should use.
Another option is to use ZipList (docs).
import Control.Applicative (ZipList(..))
-- I'm just writing this in the text box; i haven't checked if it parses.
a fs xs = getZipList $ ($) <$> (ZipList fs) <*> (ZipList xs)
ZipList is probably the worst (most verbose, without a clarity advantage) solution for this very simple situation.
Of course you could also re-implement zip by pattern matching on the lists' structures. I would not expect there to be any advantage to that, but if zip is new to you then you should take a minute to write out both versions, just for practice/understanding.
a [] _ = []
a _ [] = []
a (f:fs) (x:xs) = ...
A slight improvement over #ShapeOfMatter's excellent answer is:
import Control.Applicative (ZipList(..))
a :: [a -> b] -> [a] -> [b]
a fs xs = getZipList (ZipList fs <*> ZipList xs)
You can use parallel list comprehensions:
{-# LANGUAGE ParallelListComp #-}
functionList fs xs = [f x | f <- fs | x <- xs]
Do you want to have to ask for and get answers on stack overflow every time you have a problem to solve or do you want to learn how to write the code yourself? to be able to deal with the errors yourself? to learn how to fix them yourself? if so then start by including the error message in your questions. we could then show you how to use the errors as the guide to fixing your code. the point to learning Haskell is not to memorize its library functions, but to master the basics so that the code should practically write itself for you. and then you can memorize and use the library functions.
But even without the error message, isn't it clear from the examples that
functionList [\x->x+2] [2] == [4] == [(\x->x+2) 2]
and
functionList [\x->x+2, \x->x-2, \x->x*2] [2,3,6]
== [4,1,12]
== [(\x->x+2) 2, (\x->x-2) 3, (\x->x*2) 6]
? and then
functionList [\x->x-2, \x->x*2] [3,6]
== [1,12]
== [(\x->x-2) 3, (\x->x*2) 6]
and so
functionList [\x->x+2, \x->x-2, \x->x*2] [2,3,6]
== [(\x->x+2) 2] ++ [(\x->x-2) 3, (\x->x*2) 6]
== [(\x->x+2) 2] ++ functionList [\x->x-2, \x->x*2] [3,6]
? which is to say,
functionList (
(\x->x+2) : [\x->x-2, \x->x*2] )
( 2 : [3,6])
== ((\x->x+2) 2) : functionList [\x->x-2, \x->x*2] [3,6]
? and does all this really depend on the specific values used here or would it work with any functions f,g,h, ..., and their arguments -- any number of them?
So can it be generalized?
This question already has answers here:
Calculate n-ary Cartesian Product
(6 answers)
Closed 2 years ago.
In order to combine 2 lists the following code could be used.
[(x,y) | x <- [1, 2, 3], y <- [4, 5, 6]]
Or
(,) <$> [1,2,3] <*> [4,5,6]
Which produce
[(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
How could this be done where given a list of N lists rather than 2 lists they would be combined in such a way?
Preferebly using list comprehenison if possible as I find it the easiest to interpret.
sequence :: (Traversable t, Monad m) => t (m a) -> m (t a) does that:
> sequence [[1,2,3] , [4,5,6]]
[[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]]
> sequence [[1,2,3] , [4,5,6] , [7]]
[[1,4,7],[1,5,7],[1,6,7],[2,4,7],[2,5,7],[2,6,7],[3,4,7],[3,5,7],[3,6,7]]
There's no arbitrary-length tuples in Haskell though, so lists must be used to collect the resulting "tuples", instead.
sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a) is actually enough here, but lists' applicative functors and monads are the same, so it doesn't matter.
If any of the lists could be infinite, some diagonalization scheme must be employed if more fair enumeration is desired (see e.g. Cartesian product of infinite lists in Haskell etc.).
To implement it yourself, recursion must be employed,
ncart :: [[a]] -> [[a]]
ncart (xs:t) = [ x:r | x <- xs, r <- ncart t]
ncart [] = [[]]
(but see haskell running out of memory with finite lists for an important discussion).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Can some sort of if statement be used inside list comprehension to determine one of several outcomes for each element of a list?
Say I have a list comprehension over a list that contains elements which are either a 0 or a 1.
If the value is a 0, then the string "off" needs to be stored in another list in the same position. If the value is 1 then "on".
This is just an example. It looks easily done with recursion, but what if this needs to be done on a list of lists? Or lists of lists of lists?
Yes, of course you can:
on_or_off_list xs = [if x == 0 then "off" else "on" | x <- xs]
Or in a more point-free style:
on_or_off 0 = "off"
on_or_off _ = "on"
on_or_off_list = map on_or_off
Yes, using mutually-exclusive tests in singleton lists with guards:
foo :: (Num a, Eq a) => [a] -> [String]
foo xs = [s | x <- xs, s <- ["off" | x==0] ++ ["on" | x==1]]
Or you could just use the if expression directly,
bar :: (Num a, Eq a) => [a] -> [String]
bar xs = [s | x <- xs, let s = if x==0 then "off" else "on"]
This answers your specific question.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have these exercises
Define a function to count the total negative numbers in a list. ##
I've tried this
negative :: [Int] -> Int
negative list = [ x | x <- list, if list<0 then x=1 else x=0]
And also
Define the function
choose :: Int -> [Int] -> [Int]
that chooses all occurrences of an integer n in a list. For example
chooses 1 [1, 2, 1, 4, 5, 1] results in [1, 1, 1] choosing 1 [2, 3, 4, 6] results []
I've tried this
choose :: Int->[Int]->[Int]
choose xs ys s [rep-rep<-xs,z<-ys,rep-z]
Or
rep ::Int->[Int]->[Int]
rep _ [][]
rep a (b:bs)-a-b-a:rep a []
|otherwise-rep a (bs)
rp :: [Int] -> [Int] -> [Int]
rp [] (ys)[]
rp (x:xs) (ys)-k++rp (xs) (ys)
where k'rep x (ys)
My teacher never explained this to us that's why I have these doubts, I'm new to haskell
The expression:
negative :: [Int] -> Int
negative list = [ x | x <- list, if list<0 then x=1 else x=0]
Makes no sense for several reasons:
the result type is an Int, so by using list comprehension as outer expression, you are generating a list;
x is an element of the list x <- list, if list < 0 then … else … makes no sense since list is a list, and can not be compared with a single element; and
variables can not be assigned a new value. Variables are defined once, here by x <- list. You can make a more locally scoped variable with the same name, but that is not a good idea here.
You can just use filter :: (a -> Bool) -> [a] -> [a] here to filter the list and only retain the elements less than 0 and then calculate the length :: Foldable f => f a -> Int:
negative :: [Int] -> Int
negative list = length (filter (< 0) list)
we can make these point-free, and let this work with any Num type:
negative :: (Num a, Ord a) => [a] -> Int
negative = length . filter (< 0)
This question already has answers here:
List partitioning implemented recursively
(2 answers)
Closed 7 years ago.
I need to write a function that produces all of the possible partitions of a list, including non-contiguous partitions. It should look something like this:
*Main> ps [1,2,3,4]
[[21, 3, 4],[31, 2, 4],[41, 2, 3],[431, 2],[21, 43],[4321],[31, 42],[421, 3],[41, 32],[321, 4],[1, 32, 4],[1, 42, 3],[1, 432],[1, 2, 43],[1, 2, 3, 4]]
So far I have only been able to produce a recursive function using list comprehension to produce the contiguous partitions.
ps [] = [[]]
ps (x:xs) = [[x]:qs | qs <- ps xs] ++ [(x:gs):gss | (gs):gss <- ps xs]
I have an idea of moving the tail of each partition and prepending it to the first element of each partition, but I am not sure how I would do this in Haskell. I'm still a newbie to this language. Any help would be greatly appreciated!
Here is the function you need:
bloat :: a -> [[a]] -> [[[a]]]
bloat x [] = [[[x]]]
bloat x (xs:xss) = ((x:xs):xss) : map (xs:) (bloat x xss)
E.g. bloat 'a' ["b", "c", "de"] equals
[["ab","c","de"],["b","ac","de"],["b","c","ade"],["b","c","de","a"]]
i.e. prepend a to each sublist (and at the end of the list) and duplicate the remaining sublists.
Then partitionSet is simply
partitionSet :: [a] -> [[[a]]]
partitionSet [] = [[]]
partitionSet (x:xs) = [ys | yss <- partitionSet xs, ys <- bloat x yss]
Or in more idiomatic Haskell
partitionSet :: [a] -> [[[a]]]
partitionSet = foldr (\x r -> r >>= bloat x) [[]]