I am trying to write haskell function that takes list of lists and find the lowest value of all the high values.
So the function takes the list [[1,1,3],[2,5],[1]] and return 1 because its the lowest of 3,5,1.
What haskell function can I use?
Using list comprehension :
maxi xxs = minimum [ maximum a | a <- xxs]
(I'm a beginner in Haskell ... and coding. It's the first time that I figure it out an answer arround here. So, Gratzz to me!! :P )
Data.List contains useful functions,
:browse Data.List
in ghci.
(Looks a lot like homework, so...)
Think "step by step": First you need find all maximums of the individual lists, e.g.:
map maximum [[1,1,3],[2,5],[1]]
--[3,5,1]
Then you need the minimum of this list. So one solution would be:
minOfMax xs = minimum (map maximum xs)
Of course you can also write your own recursive solution, or use a fold:
minOfMax (x:xs) = foldl f (maximum x) xs where
f a bs = min a (maximum bs)
Related
In Haskell, given a list of lists, where each sublist contains any number of integers, how can I write a function that returns the total number of elements in all the lists?
For example if my list is:
[[1,2,3],[4,3],[2,1],[5]]
The function would return 8, since there are 8 total elements in the list of lists. I know you can use length [] to get the length of a normal list, but how do I do this with a list of lists? I would assume the solution to be recursive, but could use some help, since I am new to the language.
Three ways:
Get the length of each inner list, and sum them all:
GHCi> sum (fmap length [[1,2,3],[4,3],[2,1],[5]])
8
(Note this is equivalent to Thomas English's answer: map is fmap specialised to lists.)
Flatten the list of lists, and then get the length:
GHCi> length (concat [[1,2,3],[4,3],[2,1],[5]])
8
Use the Compose wrapper, which will make length drill through the two layers of lists.
GHCi> import Data.Functor.Compose
GHCi> length (Compose [[1,2,3],[4,3],[2,1],[5]])
8
(While explaining exactly what is going on here is a little bit tricky -- in a nutshell, we are exploiting that Compose has a Foldable instance -- behind the scenes it boils down to something very much like the first solution.)
I would assume the solution to be recursive
Indeed. It's just that the additional recursion is performed by the other functions we use (fmap for lists, sum, concat, etc.), and so we don't have to write the recursive algorithms explicitly.
You should check out how to use the 'map' function. Learn You a Haskell is a good resource to learn more!
mylist = [[1,2,3],[4,3],[2,1],[5]]
-- Get the length of each sublist with map
sublist_lengths = map length mylist
-- sublist_lengths = [3, 2, 2, 1]
result = sum sublist_lengths
One additional (pedantic) solution using folds:
foldr ((+) . foldr ((+) . const 1) 0) 0
-- or more simply:
foldr ((+) . length) 0
This incredibly ugly fold generalizes to:
sum [1 | xs <- xss, x <- xs]
which is certainly easier to read.
So all you need is to treat each list in the list as separate. What tools can do that? As Adam Smith demonstrates foldr is probably the tool of choice however fmap looks good, too and may be shorter.
What other tools are there? One of my favorites, the list comprehension.
The basic list comprehension lets you process each element of a list in turn.
For yours:
yourList = [[1,2,3],[4,3],[2,1],[5]]
[length l | l <- yourList] -- gets the length of each list and
sum [length l | l <- yourList] -- adds up all the lengths produced
I can't post the my function that is giving me bother, but basically, I'm having run time problems in my implementation of an A* Search using a heuristic which applies the ceiling function onto the straight line distance between two points. Throughout the function I refer to a list I define at the end using "where", and I believe it is a function within this list causing the runtime problems (as when I remove it, it runs quickly), but I don't understand why because it isn't a complicated function at all. This leads me to believe that the function may be trying to recreate the list every time it is referenced, instead of just once and using the already formed list each time which may be slowing it down, and causing runtimes to increase exponentionally.
i.e. As a basic example, I have referenced "myList" 3 times in the function.
function :: Int -> [Int]
function x = head (myList) : (maximum (myList) : minimum (myList))
where myList = [snd pair | pair <- (zip [0..] [sortBy compare [5*x,3-x,99*x]])]
Does this take the same computational time as...
function 5 = head ([snd pair | pair <- (zip [0..] [sortBy compare [5*5,3-5,99*5]])])
: (maximum ([snd pair | pair <- (zip [0..] [sortBy compare [5*5,3-5,99*5]])])
: minimum ([snd pair | pair <- (zip [0..] [sortBy compare [5*5,3-5,99*5]])]))
i.e. it forms the list from scratch three times throughout the function, even though the result would always be the same.
Or does it calculate it once, and use that value whenever the function is called?
I don't know quite what it would look like otherwise, but as a bit of a muddle of pseudocode and Haskell, I imagine it would go something like this.
function 5...
-- First step, Calculate myList
MyList = [snd pair | pair <- (zip [0..] [sortBy compare [5*5,3-5,99*5]])]
= [-2,25,495]
--Second step, calculate function using myList = [-2,25,495]
function 5 = head (myList) : (maximum (myList) : minimum (myList))
= head [-2,25,495] : maximum [-2,25,495] : minimum [-2,25,495]
= -2 : (495 : -2)
= [-2,495,-2]
I hope it's not too difficult to understand what I am trying to ask here.
Any assistance would be much appreciated, thanks!
The Haskell report does not say how it is evaluated: it merely specifies what the result is.
However, GHC will calculate such list only once. This can have a positive effect on peformance if the list is expensive to produce, since it will be produced only once. Mind that, in some cases, it can also have a negative effect on performance: for instance, (silly example)
let bigList = [1..1000000]
in foldl' (+) 0 bigList + foldl' (-) 0 bigList
will keep the large list in memory until both folds are computed. Instead,
foldl' (+) 0 [1..1000000] + foldl' (-) 0 [1..1000000]
can run in constant space, since the list elements can be garbage collected as soon as they are produced.
For instance, using a 50M list, the first makes GHCi spike to 2.5GB resident memory, and then to return to 100MB. The second has no noticeable effect.
Hello studying Haskell I came up at an exercise at the web that it requested to create a list given an integer the way described below:
for example if integer was 3 then a list should be generated that it contains the following:
[[3],[1,2],[2,1],[1,1,1]]
note
3=3
1+2=3
2+1=3
1+1+1=3
if integer was 2 then it would be:
[[2],[1,1]]
I cannot think a way of implementing this, so can you provide me with any hints? I believe that I must use list comprehension but I cannot think anything further than this
Always start with a type signature:
sums :: Int -> [[Int]]
Now, let's think about the recursion.
What is the base case? Can you think of a number for which the answer is trivial?
Let's say you've implemented your function and it works for all numbers under 10, so sums 9 for example returns the right answer. How would you implement sums 10?
Don't bother yourself with implementation details (e.g. List comprehension vs. filter and map) until you've answered these questions.
And another tip: Haskell programmers love to show off and create tiny-pointfree functions, but don't let it confuse you. Getting things to work is the important thing. It's better to have a working yet somewhat "ugly" solution than to stare at the screen looking for an elegant one.
Good luck!
Looks a bit like partitioning a list. A bit of googling turns up this
http://www.haskell.org/pipermail/beginners/2011-April/006832.html
partitions [] = [[]]
partitions (x:xs) = [[x]:p | p <- partitions xs]
++ [(x:ys):yss | (ys:yss) <- partitions xs]
which produces something like this
*Main> partitions "abc"
[["a","b","c"],["a","bc"],["ab","c"],["abc"]]
now all you have to do is get the length of the inner lists
map (map length) (partitions "abc")
[[1,1,1],[1,2],[2,1],[3]]
you can also change partitions to give you the result directly
partitions' 0 = [[]]
partitions' n = [1:p | p <- partitions' (n-1)]
++ [(1+ys):yss | (ys:yss) <- partitions' (n-1)]
I am new to Haskell and am trying to learn the basics. I am having a hard time understanding how to manipulate the contents of a list.
Assume I have the following list and I would like to create a function to subtract 1 from every element in the list, where I can simply pass x to the function, how would this be done?
Prelude>let x = 1:2:3:4:5:[]
Something like:
Prelude>subtractOne(x)
(You can write 1:2:3:4:5:[] more simply as [1,2,3,4,5] or even [1..5].)
Comprehensions
You'd like to use list comprehensions, so here it is:
subtractOne xs = [ x-1 | x <- xs ]
Here I'm using xs to stand for the list I'm subtracting one from.
The first thing to notice is x <- xs which you can read as "x is taken from xs". This means we're going to take each of the numbers in xs in turn, and each time we'll call the number x.
x-1 is the value we're calculating and returning for each x.
For more examples, here's one that adds one to each element [x+1|x<-xs] or squares each element [x*x|x<-xs].
More than one list
Let's take list comprehension a little further, to write a function that finds the squares then the cubes of the numbers we give it, so
> squaresAndCubes [1..5]
[1,4,9,16,25,1,8,27,64,125]
We need
squaresAndCubes xs = [x^p | p <- [2,3], x <- xs]
This means we take the powers p to be 2 then 3, and for each power we take all the xs from xs, and calculate x to the power p (x^p).
What happens if we do that the other way around?
squaresAndCubesTogether xs = = [x^p | x <- xs, p <- [2,3]]
We get
> squaresAndCubesTogether [1..5]
[1,1,4,8,9,27,16,64,25,125]
Which takes each x and then gives you the two powers of it straight after each other.
Conclusion - the order of the <- bits tells you the order of the output.
Filtering
What if we wanted to only allow some answers?
Which numbers between 2 and 100 can be written as x^y?
> [x^y|x<-[2..100],y<-[2..100],x^y<100]
[4,8,16,32,64,9,27,81,16,64,25,36,49,64,81]
Here we allowed all x and all y as long as x^y<100.
Since we're doing exactly the same to each element, I'd write this in practice using map:
takeOne xs = map (subtract 1) xs
or shorter as
takeOne = map (subtract 1)
(I have to call it subtract 1 because - 1 would be parsed as negative 1.)
You can do this with the map function:
subtractOne = map (subtract 1)
The alternative solution with List Comprehensions is a little more verbose:
subtractOne xs = [ x - 1 | x <- xs ]
You may also want to add type annotations for clarity.
You can do this quite easily with the map function, but I suspect you want to roll something yourself as a learning exercise. One way to do this in Haskell is to use recursion. This means you need to break the function into two cases. The first case is usually the base case for the simplest kind of input. For a list, this is an empty list []. The result of subtracting one from all the elements of the empty list is clearly an empty list. In Haskell:
subtractOne [] = []
Now we need to consider the slightly more complex recursive case. For any list other than an empty list, we can look at the head and tail of the input list. We will subtract one from the head and then apply subtractOne to the rest of the list. Then we need to concatenate the results together to form a new list. In code, this looks like this:
subtractOne (x:xs) = (x - 1) : subtractOne xs
As I mentioned earlier, you can also do this with map. In fact, it is only one line and the preferred Haskellism. On the other hand, I think it is a very good idea to write your own functions which use explicit recursion in order to understand how it works. Eventually, you may even want to write your own map function for further practice.
map (subtract 1) x will work.
subtractOne = map (subtract 1)
The map function allows you to apply a function to each element of a list.
So, I'm new here, and I would like to ask 2 questions about some code:
Duplicate each element in list by n times. For example, duplicate [1,2,3] should give [1,2,2,3,3,3]
duplicate1 xs = x*x ++ duplicate1 xs
What is wrong in here?
Take positive numbers from list and find the minimum positive subtraction. For example, [-2,-1,0,1,3] should give 1 because (1-0) is the lowest difference above 0.
For your first part, there are a few issues: you forgot the pattern in the first argument, you are trying to square the first element rather than replicate it, and there is no second case to end your recursion (it will crash). To help, here is a type signature:
replicate :: Int -> a -> [a]
For your second part, if it has been covered in your course, you could try a list comprehension to get all differences of the numbers, and then you can apply the minimum function. If you don't know list comprehensions, you can do something similar with concatMap.
Don't forget that you can check functions on http://www.haskell.org/hoogle/ (Hoogle) or similar search engines.
Tell me if you need a more thorough answer.
To your first question:
Use pattern matching. You can write something like duplicate (x:xs). This will deconstruct the first cell of the parameter list. If the list is empty, the next pattern is tried:
duplicate (x:xs) = ... -- list is not empty
duplicate [] = ... -- list is empty
the function replicate n x creates a list, that contains n items x. For instance replicate 3 'a' yields `['a','a','a'].
Use recursion. To understand, how recursion works, it is important to understand the concept of recursion first ;)
1)
dupe :: [Int] -> [Int]
dupe l = concat [replicate i i | i<-l]
Theres a few problems with yours, one being that you are squaring each term, not creating a new list. In addition, your pattern matching is off and you would create am infinite recursion. Note how you recurse on the exact same list as was input. I think you mean something along the lines of duplicate1 (x:xs) = (replicate x x) ++ duplicate1 xs and that would be fine, so long as you write a proper base case as well.
2)
This is pretty straight forward from your problem description, but probably not too efficient. First filters out negatives, thewn checks out all subtractions with non-negative results. Answer is the minumum of these
p2 l = let l2 = filter (\x -> x >= 0) l
in minimum [i-j | i<-l2, j<-l2, i >= j]
Problem here is that it will allow a number to be checkeed against itself, whichwiull lend to answers of always zero. Any ideas? I'd like to leave it to you, commenter has a point abou t spoon-feeding.
1) You can use the fact that list is a monad:
dup = (=<<) (\x -> replicate x x)
Or in do-notation:
dup xs = do x <- xs; replicate x x; return x
2) For getting only the positive numbers from a list, you can use filter:
filter (>= 0) [1,-1,0,-5,3]
-- [1,0,3]
To get all possible "pairings" you can use either monads or applicative functors:
import Control.Applicative
(,) <$> [1,2,3] <*> [1,2,3]
[(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)]
Of course instead of creating pairs you can generate directly differences when replacing (,) by (-). Now you need to filter again, discarding all zero or negative differences. Then you only need to find the minimum of the list, but I think you can guess the name of that function.
Here, this should do the trick:
dup [] = []
dup (x:xs) = (replicate x x) ++ (dup xs)
We define dup recursively: for empty list it is just an empty list, for a non empty list, it is a list in which the first x elements are equal to x (the head of the initial list), and the rest is the list generated by recursively applying the dup function. It is easy to prove the correctness of this solution by induction (do it as an exercise).
Now, lets analyze your initial solution:
duplicate1 xs = x*x ++ duplicate1 xs
The first mistake: you did not define the list pattern properly. According to your definition, the function has just one argument - xs. To achieve the desired effect, you should use the correct pattern for matching the list's head and tail (x:xs, see my previous example). Read up on pattern matching.
But that's not all. Second mistake: x*x is actually x squared, not a list of two values. Which brings us to the third mistake: ++ expects both of its operands to be lists of values of the same type. While in your code, you're trying to apply ++ to two values of types Int and [Int].
As for the second task, the solution has already been given.
HTH