Related
im learning functional programming with Haskell and i have this exercise where i have something like [a], z, with [a] any kind of list and z the element that im gonna erase inside [a]. This problem it's kinda easy to solve (even for a newbie like me in Haskell) but I am having troubles with the way I need to print the output.
I need to create a tuple where the first element is the list without any z element and the number of times that it found z inside of a. Couple examples:
Input: [2,3,4,2,2] 2
Output: ([3,4],3)
Input: [1,1,1,1] 1
Output: ([],4)
Input: [1,2,3,4] 5
Output: ([1,2,3,4],0)
So far i've done something like this but I don't know how to keep going:
ex3 :: (Eq a, Num a) => [a] -> a -> ([a],Int)
ex3 [] _ = ([],0)
ex3 (x:xs) z | x == z = (xs,1) -- this line is wrong, but idk how to fix it
| otherwise = ([0],0) -- same here
I've done both problems individually (deleting z elements and counting how many times z is in [a]. Looks like this:
a) Deleting z elements:
ex3a :: (Eq a) => [a] -> a -> [a]
ex3a [] _ = []
ex3a (x:xs) z | x == z = ex3a xs z
| otherwise = x : ex3a xs z
b) Counting how many times z is in [a]:
ex3b :: (Eq a) => [a] -> a -> Int
ex3b [] _ = 0
ex3b (x:xs) z | x == z = 1 + ex3b xs z
| otherwise = ex3b xs z
Usually it helps to think of functions like in mathematics you think about inductive definitions. For example the first line of your function can read like:
"The ex3 of an empty list, and any element is a tuple containing the empty list and zero"
ex3 [] _ = ([], 0)
For non-empty lists of course the problem is a bit harder. Like in your code, there are basically two cases here.
"The ex3 of a non-empty list and an element z where the head of the list is not equal to z is the same as the ex3 of the tail of the list, but prepended with the head of that list", so we can write it like:
ex3 [] _ = ([], 0)
ex3 (x:xs) z | x /= z = (x:t, n)
| otherwise = ...
where (t, n) = ex3 xs z
So here we make a recursive call to ex3 with the tail of the list xs, and we obtain the result tuple (t, n), so t contains the "erased" tail, and n the number of times we removed the element, and in case x /= z, then we can return (x:t, n), since the number of removals does not change, but we have to prepend x to the list.
"The ex3 of a non-empty list and an element z where the head of the list is equal to z is the same as the ex3 of the tail of the list but with an incremented count", so:
ex3 :: (Eq a, Num n) => [a] -> a -> ([a], n)
ex3 [] _ = ([], 0)
ex3 (x:xs) z | x /= z = (x:t, n)
| otherwise = (t, n+1)
where (t, n) = ex3 xs z
We then obtain the expected results:
Prelude> ex3 [2,3,4,2,2] 2
([3,4],3)
Prelude> ex3 [1,1,1,1] 1
([],4)
Prelude> ex3 [1,2,3,4] 5
([1,2,3,4],0)
Just for fun, this is how I would implement that function:
import Data.Foldable
import Data.Monoid
ex3 :: Eq a => [a] -> a -> ([a], Int)
ex3 haystack needle = getSum <$> foldMap inject haystack where
inject hay | hay == needle = ([], 1)
| otherwise = ([hay], 0)
What I like about this is that the recursion pattern is immediately obvious -- at least to those familiar with Haskell's standard library -- without careful scrutiny (because it is just a call to foldMap).
The partition function consumes a predicate and a list; it produces a pair of lists whose first element satisfies the predicate, the second doesn't.
import Data.List (partition)
ex4 :: Eq a => [a] -> a -> ([a], Int)
ex4 xs x = length <$> partition (/= x) xs
I am trying to learn Haskell and I want to solve one task. I have a list of Integers and I need to add them to another list if they are bigger then both of their neighbors. For Example:
I have a starting list of [0,1,5,2,3,7,8,4] and I need to print out a list which is [5, 8]
This is the code I came up but it returns an empty list:
largest :: [Integer]->[Integer]
largest n
| head n > head (tail n) = head n : largest (tail n)
| otherwise = largest (tail n)
I would solve this as outlined by Thomas M. DuBuisson. Since we want the ends of the list to "count", we'll add negative infinities to each end before creating triples. The monoid-extras package provides a suitable type for this.
import Data.Monoid.Inf
pad :: [a] -> [NegInf a]
pad xs = [negInfty] ++ map negFinite xs ++ [negInfty]
triples :: [a] -> [(a, a, a)]
triples (x:rest#(y:z:_)) = (x,y,z) : triples rest
triples _ = []
isBig :: Ord a => (a,a,a) -> Bool
isBig (x,y,z) = y > x && y > z
scnd :: (a, b, c) -> b
scnd (a, b, c) = b
finites :: [Inf p a] -> [a]
finites xs = [x | Finite x <- xs]
largest :: Ord a => [a] -> [a]
largest = id
. finites
. map scnd
. filter isBig
. triples
. pad
It seems to be working appropriately; in ghci:
> largest [0,1,5,2,3,7,8,4]
[5,8]
> largest [10,1,10]
[10,10]
> largest [3]
[3]
> largest []
[]
You might also consider merging finites, map scnd, and filter isBig in a single list comprehension (then eliminating the definitions of finites, scnd, and isBig):
largest :: Ord a => [a] -> [a]
largest xs = [x | (a, b#(Finite x), c) <- triples (pad xs), a < b, c < b]
But I like the decomposed version better; the finites, scnd, and isBig functions may turn out to be useful elsewhere in your development, especially if you plan to build a few variants of this for different needs.
One thing you might try is lookahead. (Thomas M. DuBuisson suggested a different one that will also work if you handle the final one or two elements correctly.) Since it sounds like this is a problem you want to solve on your own as a learning exercise, I’ll write a skeleton that you can take as a starting-point if you want:
largest :: [Integer] -> [Integer]
largest [] = _
largest [x] = _ -- What should this return?
largest [x1,x2] | x1 > x2 = _
| x1 < x2 = _
| otherwise = _
largest [x1,x2,x3] | x2 > x1 && x2 > x3 = _
| x3 > x2 = _
| otherwise = _
largest (x1:x2:x3:xs) | x2 > x1 && x2 > x3 = _
| otherwise = _
We need the special case of [x1,x2,x3] in addition to (x1:x2:x3:[]) because, according to the clarification in your comment, largest [3,3,2] should return []. but largest [3,2] should return [3]. Therefore, the final three elements require special handling and cannot simply recurse on the final two.
If you also want the result to include the head of the list if it is greater than the second element, you’d make this a helper function and your largest would be something like largest (x1:x2:xs) = (if x1>x2 then [x1] else []) ++ largest' (x1:x2:xs). That is, you want some special handling for the first elements of the original list, which you don’t want to apply to all the sublists when you recurse.
As suggested in the comments, one approach would be to first group the list into tuples of length 3 using Preludes zip3 and tail:
*Main> let xs = [0,1,5,2,3,7,8,4]
*Main> zip3 xs (tail xs) (tail (tail xs))
[(0,1,5),(1,5,2),(5,2,3),(2,3,7),(3,7,8),(7,8,4)]
Which is of type: [a] -> [b] -> [c] -> [(a, b, c)] and [a] -> [a] respectively.
Next you need to find a way to filter out the tuples where the middle element is bigger than the first and last element. One way would be to use Preludes filter function:
*Main> let xs = [(0,1,5),(1,5,2),(5,2,3),(2,3,7),(3,7,8),(7,8,4)]
*Main> filter (\(a, b, c) -> b > a && b > c) xs
[(1,5,2),(7,8,4)]
Which is of type: (a -> Bool) -> [a] -> [a]. This filters out elements of a list based on a Boolean returned from the predicate passed.
Now for the final part, you need to extract the middle element from the filtered tuples above. You can do this easily with Preludes map function:
*Main> let xs = [(1,5,2),(7,8,4)]
*Main> map (\(_, x, _) -> x) xs
[5,8]
Which is of type: (a -> b) -> [a] -> [b]. This function maps elements from a list of type a to b.
The above code stitched together would look like this:
largest :: (Ord a) => [a] -> [a]
largest xs = map (\(_, x, _) -> x) $ filter (\(a, b, c) -> b > a && b > c) $ zip3 xs (tail xs) (tail (tail xs))
Note here I used typeclass Ord, since the above code needs to compare with > and <. It's fine to keep it as Integer here though.
I need to create a weight matrix essentially by multiplying all the elements of a list with themselves.
for example if my list is [1;-1;1;-1], the resulting matrix would be
[[0;-1;1;-1],
[-1;0;-1;1],
[1;-1;0;-1],
[-1;1;-1;0]]
(diagonal is filled with 0's because a node shouldn't be able to lead to itself)
This would be a piece of cake, but it has to be done recursively, with the following constraints:
only List.hd, List.tl and List.nth can be used, and as a parameter, I can only pass in the list:
let rec listMatrix = fun(myList)->...
Is there any way to do this? Or should I just try to find some fundamentally different way to solve this problem?
Also, only functional approach is allowed, no global variables.
One way to do it recursively is as follows:
let l = [1;-1;1;-1];;
let rec index xs =
let idx xs i = match xs with
[] -> []
| (x::xss) -> (i,x) :: idx xss (i+1)
in idx xs 0
fst (x,y) = x
snd (x,y) = y
let rec mult xs ys = match xs with
[] -> []
| (x::xss) -> (List.map (fun y->if (fst x == fst y) then 0 else (snd y*snd x)) ys) :: (mult xss ys)
let mult0 xs = mult (index xs) (index xs)
What the code does is, as asked, multiplying a vector with itself. The vector is indexed with numbers in order to handle diagonal elements specially.
The output is:
# mult0 l;;
- : int list list =
[[0; -1; 1; -1]; [-1; 0; -1; 1]; [1; -1; 0; -1]; [-1; 1; -1; 0]]
I'm pretty new to Haskell, and I'm having a little trouble. I'm trying to implement a function that takes a list, and an int. the int is supposed to be the index k at which the list is split into a pair of lists. The first one containing the first k elements of the list, and the second from k+1 to the last element. Here's what I have so far:
split :: [a] -> Int -> ([a], [a])
split [] k = error "Empty list!"
split (x:[]) k = ([x],[])
split xs k | k >= (length xs) = error "Number out of range!"
| k < 0 = error "Number out of range!"
I can't actually figure out how to do the split. Any help would be appreciated.
First of all, note that the function you are trying to construct is already in the standard library, in the Prelude - it is called splitAt. Now, directly looking at its definition is confusing, as there are two algorithms, one which doesn't use the standard recursive structure at all -splitAt n xs = (take n xs, drop n xs) - and one that is hand-optimized making it ugly. The former makes more intuitive sense, as you are simply taking a prefix and a suffix and putting them in a pair. However, the latter teaches more, and has this overall structure:
splitAt :: Int -> [a] -> ([a], [a])
splitAt 0 xs = ([], xs)
splitAt _ [] = ([], [])
splitAt n (x:xs) = (x:xs', xs'')
where
(xs', xs'') = splitAt (n - 1) xs
The basic idea is that if a list is made up of a head and a tail (it is of the form x:xs), then the list going from index k+1 onwards will be the same as the list going from k onwards once you remove the first element - drop (k + 1) (x : xs) == drop k xs. To construct the prefix, you similarly remove the first element, take a smaller prefix, and stick the element back on - take (k + 1) (x : xs) == x : take k xs.
What about this:
splitAt' = \n -> \xs -> (take n xs, drop n xs)
Some tests:
> splitAt' 3 [1..10]
> ([1,2,3],[4,5,6,7,8,9,10])
> splitAt' 0 [1..10]
> ([],[1,2,3,4,5,6,7,8,9,10])
> splitAt' 3 []
> ([],[])
> splitAt' 11 [1..10]
> ([1,2,3,4,5,6,7,8,9,10],[])
> splitAt' 2 "haskell"
> ("ha","skell")
Basically, you need some way of passing along partial progress as you recurse through the list. I used a second function that takes an accumulator parameter; it is called from split and then calls itself recursively. There are almost certainly better ways..
EDIT: removed all the length checks., but I believe the use of ++ means it's still O(n^2).
split xs k | k < 0 = error "Number out of range!"
split xs k = ssplit [] xs k
ssplit p xs 0 = (p, xs)
ssplit p (x:xs) k = ssplit (p++[x]) xs (k-1)
ssplit p [] k = error "Number out of range!"
to get the behavior in the original post or
ssplit p [] k = (p,[])
To get the more forgiving behavior of the standard splitAt function.
A common trick for getting rid of quadratic behavior in building a list is to build it up backwards, then reverse it, modifying Mark Reed's solution:
split xs k | k < 0 = error "Number out of range!"
split xs k = (reverse a, b)
where
(a,b) = ssplit [] xs k
ssplit p xs 0 = (p, xs)
ssplit p (x:xs) k = ssplit (x:p) xs (k-1)
ssplit p [] k = error "Number out of range!"
The error check in ssplit is fine since won't get checked (one of the earlier patterns will match) unless there is an actual error.
In practice you might want to add a few strictness annotations to ssplit to manage stack growth, but that's a further refinement.
See splitAt in the prelude:
ghci> :t flip splitAt
flip splitAt :: [a] -> Int -> ([a], [a])
ghci> flip splitAt ['a'..'j'] 5
("abcde","fghij")
This is homework that has been driving crazy for the last couple of days.
I got a list that I am applying a function to - pushing each element to the right if the element next to it is smaller then the previous one.
My function to pass over the list once and sort the head of the list:
sortEm lis#(x:y:xs) = if x > y then y: sortEm (x:xs) else lis
sortEm [x] = [x]
sortEm [] = []
myList (x:y:xs) = if x > y then sortEm lis else x:myList(y:xs)
myList [] = []
myList [x] = [x]
But my problem is that once that sortem has finished it returns either an empty list or a list containing one element, how would i design this the functional way?
I was thinking about foldl and some haskell magic to go along with that but currently I am stuck.
Thanks in advance
First of, your sortEm function name is misleading, it doesn't sort its argument list but inserts its head element into its tail. As it happens, there is an insert function already in Data.List module that inserts its first argument into the 2nd, so there's an equivalency
sortEm (x:xs) === Data.List.insert x xs
Now, inserting an item will only get you a sorted list back if you're inserting it into a list that is already sorted. Since empty list is sorted, that's what myList function does that you got in dave4420's answer. That is an "insertion" sort, progressively inserting elements of list into an auxiliary list, initially empty. And that's what the 2nd function does that you got in dave4420 answer:
insertionSort xs = foldr Data.List.insert [] xs
This does "apply sortem" i.e. inserts, "each element" only once. For a list [a,b,c,...,z] it's equivalent to
insert a (insert b (insert c (... (insert z []) ...)))
What you probably meant in your comment, i.e. comparing (and possibly swapping) two neighboring elements "only once", is known as bubble sort. Of course making only one pass through the list won't get it sorted, in a general case:
bubbleOnce xs = foldr g [] xs where
g x [] = [x]
g x xs#(y:ys) | x>y = y:x:ys -- swap x and y in the output
| otherwise = x:xs -- keep x before y in the output
Now, bubbleOnce [4,2,6,1,8] ==> [1,4,2,6,8]. The value that you expected, [2,4,1,6,8], would result from applying the folding function g in an opposite direction, from the left to the right. But that's much less natural to do here with Haskell lists:
bubbleOnce' [] = []
bubbleOnce' (x:xs) = let (z,h)=foldl g (x,id) xs in (h [z]) where
g (x,f) y | x>y = (x, f.(y:)) -- swap x and y in the output
| otherwise = (y, f.(x:)) -- keep x before y in the output
(edit:) see jimmyt's answer for the equivalent, but simple and nice version using straightforward recursion. It is also lazier (less strict) than both the fodlr and foldl versions here.
myList [] = []
myList (x : xs) = sortEm (x : myList xs)
(untested)
Or in terms of a fold:
myList = foldr cons []
where cons x xs = sortEm (x : xs)
(also untested)
-- if..then..else version
sortEM :: Ord a => [a] -> [a]
sortEM (x:y:xs) = if x < y
then x : sortEM (y:xs)
else y : sortEM (x:xs)
sortEM b = b
-- guard version
sortEM_G :: Ord a => [a] -> [a]
sortEM_G (x:y:xs)
| x < y = x : sortEM_G (y:xs)
| otherwise = y : sortEM_G (x:xs)
sortEM_G b = b