This is a general question in relation to cons ( | ) operator in erlang. I'm going over a sample exam and there exists this question:
f2([A1, A2 | A1]) ->
{A2, A1};
f2([A, true | B]) ->
{A, B};
f2([A1, A2 | _]) ->
{A1, A2};
f2([_ | B]) ->
[B];
f2([A]) ->
{A};
f2(_) ->
nothing_matched.
I am confused as to why the following input: ([[a], [b] , a]) results in the output: {[b], [a]}
Why is this? From my understanding if the split from the second element in the list (which is the empty list, []) is the same as the first element, then the output will be: A2, A1. If the 3rd element a becomes a list, [a], then the output is then: {[a], [b]}. Why?
This is because in proper list the right side of [... | ...] operator is expected to be a list. Elements on the left are attached or extracted values of head elements which can be other lists too, it doesn't matter. Last element of left side points to right side. It means that in this case first element matches the tail list
[A1, A2 | A1] = [[a], [b], a] = [[a], [b] | [a]] = [[a], [b]] ++ [a].
You can't write [a,b,c | d,e,f,g], you can have only one tail. But [a,b,c | [d,e,f,g]] will work and is equal to [a,b,c,d,e,f,g]. It means that you construct list element with value a which points to list element of value b which points to list element of value c which points to the right side (no matter what).
Its equivalent (using only a | operator without commas) is:
[a | [b | [c | [d | [e | [f | [g]]]]]]].
To understand it you should think of it rather this way than with commas.
Binding example:
[El1, El2 | Tail] = [a,b,c,d],
[El1 | [El2 | Tail]] = [a,b,c,d].
In both cases El1 = a, El2 = b and Tail = [c,d] = [c | [d]] = [c | [d | []]].
As you see [[a],[b], a] means that list element of value [a] (which is list element of value a which points to an empty list []) points to an list element of value [b] which points to an list element of value a which points to an empty list [].
Every proper list last element is pointing at empty list [] so it's true that [a,b,c] == [a,b,c | []].
But there are also improper lists and you can construct them by using non list as a tail like [a,b,c | d] but this is useful only in specific situations and most of list operations can't by applied to them. One example of usage is lazy evaluation where tail is a function.
I've just found similar question to yours, it's here.
If it's still not clear, you may find wiki page about singly linked list useful.
([[a], [b] , a]) will match the first clause f2([A1, A2 | A1]) -> {A2, A1};.
so [A1, A2 | A1] = [[a], [b] , a], you can get A1 = [a], A2 = [b], the important is the second A1, A1 = [a].
The operator | is used for a recursive definition of a list: [A|B] means that you add the element A to an existing list B. A is the first element of the resulting list, called the head, B is the rest of the list called tail. B can be also split into a head and a tail, and the process can continue until the tail is equal to the empty list [].
Your example can be written in different ways:
L = [[a], [b] , a]. % element list representation
L = [[a]|[[b]|[a|[]]]]. % cons list representation
L = [[a],[b]|[a]]. % mixed representation
In the last one you can recognize the pattern [A1, A2 | A1] of the first clause of the f2/1 function, so you get the result {A2,A1} = {[b],[a]}.
Related
dobb[] = []
dobb (x:xs) = [x * 2| x<- xs]
I am really new to haskell and started learning it this week. I want to create a function that multiplies each element in a list by 2. So the list would go from [1,2,3] to [2,4,6]. The code I have works fine, except it skips the first element of the list and goes from [1,2,3] to [4,6]. How can I make the code multiply the first element as well?
[x*2 | x<-[1..5]]
I've found this line that does what I am looking for, but I dont understand how to go from this line of code and convert it to a function that works for all lists.
I'll address your last question,
how to go from this line of code,
[x*2 | x <- [1..5]]
and convert it to a function that works for all lists[?]
This is known as generalization and is achieved by abstraction. First we name it,
foo = [x*2 | x <- [1..5]]
then we name that arbitrary piece of data we used as an example to work on,
foo = let {xs = [1..5]} in [x*2 | x <- xs]
and then we abstract over it by removing that arbitrary piece of data in the internal definition, letting it become the function parameter instead, to be specified by this, now, function's callers:
foo xs = [x*2 | x <- xs]
and there it is, the general function working on all lists, doing the same thing as it did on the specific example we used at first.
If you use the pattern (x:xs) then you unpack the list such that x is the head (first item) of the list, and xs is the tail (remaining items) of that list. For a list [1,4,2,5], x will thus refer to 1, and xs to [4,2,5].
In the list comprehension, you then use x <- xs as a generator, and thus you enumerate over the remaining elements. The x in the list comprehension is furthermore not the head of the list, but a more locally scoped variable.
You can work with list comprehension and work on the entire list, so:
dobb :: Num a => [a] -> [a]
dobb xs = [x * 2| x <- xs]
We can also work with map :: (a -> b) -> [a] -> [b] to perform the same operation on the elements:
dobb :: Num a => [a] -> [a]
dobb = map (2*)
I've done some research and I see that the List.zip function takes two lists and returns one list of tuples, but how do you change one list into a list of tuples?
let rec combinePair xs =
match xs with
| [] -> []
| [x1] -> []
| x1::x2::x3::xs -> [(x1, x2)]
| x1::x2::xs -> [(x1, x2)]
If an odd number of elements exist in the list, the last element should be dropped, if an even number of elements exist they should be returned as a list of tuples. For example
combinePair [x1; x2; x3; x4] = [(x1, x2); (x3, x4)]
Your code is almost there.
Here's the thinking:
when given an empty list, the result is an empty list (you already got that).
when given a list of one element, the result is an empty list (got that too).
otherwise, the first item of result is a tuple composed of the first two elements, and the rest of result is the result of applying the same process to the rest of the input.
This can be almost identically translated to F#:
let rec combinePair xs =
match xs with
| [] | [_] -> []
| x1::x2::rest -> (x1, x2) :: (combinePair rest)
(note how I combined the first two cases on one line, [] | [_] ->)
I'm sure there are prettier solutions but for those who are allergic to recursion:
let xsOdd = [1;2;3;4;5]
List.chunkBySize 2 xsOdd
|> List.filter (fun x -> x.Length = 2)
|> List.map (fun x -> x.[0],x.[1])
//val it : (int * int) list = [(1, 2); (3, 4)]
I have a list of tuples and I want to create the a list of elements from a specific position in the tuple.
My tuple is {A, B} and I have several of these in a list and i want to create the list of all the B elements.
Cheers!
You can use lists:map.
1> A = [{1,2},{3,4},{5,6}].
[{1,2},{3,4},{5,6}]
2> B = lists:map(fun ({_, V}) -> V end, A).
[2,4,6]
The function passed to the map will select the element required from the tuple and the result will be a list of all the elements in that particular position in the given list of tuples. The above code assumes that all tuples have same number of elements.
Yet another way is to just use a simple list comprehension:
[B || {_, B} <- L].
> L = [{a1,b1}, {a2,b2}, {a3,b3}].
[{a1,b1},{a2,b2},{a3,b3}]
> lists:foldr(fun({_, B}, Acc) -> [B | Acc] end, [], L).
[b1,b2,b3]
This is a quick sample, not tested, but it should work.
split_tuples([{A | B} | T], Acc) ->
NewAcc = [B | Acc],
split_tuples(T, NewAcc);
split_tuples([], Acc) ->
lists:reverse(Acc).
erlang's element/2 function does just that: return the nth element from a tuple.
Put that in a map or fold function, with position as a parameter, and you're done.
edit: some untested code example:
get_them_all(ListOfTuples,Index) ->
lists:map(fun(Tuple) -> element(Index,Tuple) end,ListOfTuples).
For example I have a list [1,3,5] and another list [2,4,6], how do I append these two lists in such way it will form into a List of Lists like this: [[1,3,5],[2,4,6]]?
How do I manipulate the list if I add another list at the end [7,8,9] to look like [[1,3,5],[2,4,6],[7,8,9]]?
L1 = [1,3,5],
L2 = [2,4,6],
[L1,L2].
You just need create a list containing both lists.
A = [1,3,5],
B = [2,4,6],
[A, B].
-module(lol).
-export([new/0, append/2, head/1, tail/1]).
new() -> [].
append(H, []) when is_list(H) -> [H];
append(H, T) when is_list(H) -> [H | T].
head([H | _]) when is_list(H) -> H.
tail([_ | T]) -> T.
In the shell you could then:
> Herp = lol:append([1,3,4], lol:new()).
[[1,2,3]]
> Derp = lol:append([4,5,6], Herp).
[[4,5,6],[1,2,3]]
> lol:head(Derp).
[4,5,6]
I leave the rest as exercise for the user.
1> [1,2,3 | [1,2,3]].
[1,2,3,1,2,3]
2> lists:append([1,2,3], [1,2,3]).
[1,2,3,1,2,3]
What's the most direct/efficient way to create all possibilities of dividing one (even) list into two in Haskell? I toyed with splitting all permutations of the list but that would add many extras - all the instances where each half contains the same elements, just in a different order. For example,
[1,2,3,4] should produce something like:
[ [1,2], [3,4] ]
[ [1,3], [2,4] ]
[ [1,4], [2,3] ]
Edit: thank you for your comments -- the order of elements and the type of the result is less important to me than the concept - an expression of all two-groups from one group, where element order is unimportant.
Here's an implementation, closely following the definition.
The first element always goes into the left group. After that, we add the next head element into one, or the other group. If one of the groups becomes too big, there is no choice anymore and we must add all the rest into the the shorter group.
divide :: [a] -> [([a], [a])]
divide [] = [([],[])]
divide (x:xs) = go ([x],[], xs, 1,length xs) []
where
go (a,b, [], i,j) zs = (a,b) : zs -- i == lengh a - length b
go (a,b, s#(x:xs), i,j) zs -- j == length s
| i >= j = (a,b++s) : zs
| (-i) >= j = (a++s,b) : zs
| otherwise = go (x:a, b, xs, i+1, j-1) $ go (a, x:b, xs, i-1, j-1) zs
This produces
*Main> divide [1,2,3,4]
[([2,1],[3,4]),([3,1],[2,4]),([1,4],[3,2])]
The limitation of having an even length list is unnecessary:
*Main> divide [1,2,3]
[([2,1],[3]),([3,1],[2]),([1],[3,2])]
(the code was re-written in the "difference-list" style for efficiency: go2 A zs == go1 A ++ zs).
edit: How does this work? Imagine yourself sitting at a pile of stones, dividing it into two. You put the first stone to a side, which one it doesn't matter (so, left, say). Then there's a choice where to put each next stone — unless one of the two piles becomes too small by comparison, and we thus must put all the remaining stones there at once.
To find all partitions of a non-empty list (of even length n) into two equal-sized parts, we can, to avoid repetitions, posit that the first element shall be in the first part. Then it remains to find all ways to split the tail of the list into one part of length n/2 - 1 and one of length n/2.
-- not to be exported
splitLen :: Int -> Int -> [a] -> [([a],[a])]
splitLen 0 _ xs = [([],xs)]
splitLen _ _ [] = error "Oops"
splitLen k l ys#(x:xs)
| k == l = [(ys,[])]
| otherwise = [(x:us,vs) | (us,vs) <- splitLen (k-1) (l-1) xs]
++ [(us,x:vs) | (us,vs) <- splitLen k (l-1) xs]
does that splitting if called appropriately. Then
partitions :: [a] -> [([a],[a])]
partitions [] = [([],[])]
partitions (x:xs)
| even len = error "Original list with odd length"
| otherwise = [(x:us,vs) | (us,vs) <- splitLen half len xs]
where
len = length xs
half = len `quot` 2
generates all the partitions without redundantly computing duplicates.
luqui raises a good point. I haven't taken into account the possibility that you'd want to split lists with repeated elements. With those, it gets a little more complicated, but not much. First, we group the list into equal elements (done here for an Ord constraint, for only Eq, that could still be done in O(length²)). The idea is then similar, to avoid repetitions, we posit that the first half contains more elements of the first group than the second (or, if there is an even number in the first group, equally many, and similar restrictions hold for the next group etc.).
repartitions :: Ord a => [a] -> [([a],[a])]
repartitions = map flatten2 . halves . prepare
where
flatten2 (u,v) = (flatten u, flatten v)
prepare :: Ord a => [a] -> [(a,Int)]
prepare = map (\xs -> (head xs, length xs)) . group . sort
halves :: [(a,Int)] -> [([(a,Int)],[(a,Int)])]
halves [] = [([],[])]
halves ((a,k):more)
| odd total = error "Odd number of elements"
| even k = [((a,low):us,(a,low):vs) | (us,vs) <- halves more] ++ [normalise ((a,c):us,(a,k-c):vs) | c <- [low + 1 .. min half k], (us,vs) <- choose (half-c) remaining more]
| otherwise = [normalise ((a,c):us,(a,k-c):vs) | c <- [low + 1 .. min half k], (us,vs) <- choose (half-c) remaining more]
where
remaining = sum $ map snd more
total = k + remaining
half = total `quot` 2
low = k `quot` 2
normalise (u,v) = (nz u, nz v)
nz = filter ((/= 0) . snd)
choose :: Int -> Int -> [(a,Int)] -> [([(a,Int)],[(a,Int)])]
choose 0 _ xs = [([],xs)]
choose _ _ [] = error "Oops"
choose need have ((a,k):more) = [((a,c):us,(a,k-c):vs) | c <- [least .. most], (us,vs) <- choose (need-c) (have-k) more]
where
least = max 0 (need + k - have)
most = min need k
flatten :: [(a,Int)] -> [a]
flatten xs = xs >>= uncurry (flip replicate)
Daniel Fischer's answer is a good way to solve the problem. I offer a worse (more inefficient) way, but one which more obviously (to me) corresponds to the problem description. I will generate all partitions of the list into two equal length sublists, then filter out equivalent ones according to your definition of equivalence. The way I usually solve problems is by starting like this -- create a solution that is as obvious as possible, then gradually transform it into a more efficient one (if necessary).
import Data.List (sort, nubBy, permutations)
type Partition a = ([a],[a])
-- Your notion of equivalence (sort to ignore the order)
equiv :: (Ord a) => Partition a -> Partition a -> Bool
equiv p q = canon p == canon q
where
canon (xs,ys) = sort [sort xs, sort ys]
-- All ordered partitions
partitions :: [a] -> [Partition a]
partitions xs = map (splitAt l) (permutations xs)
where
l = length xs `div` 2
-- All partitions filtered out by the equivalence
equivPartitions :: (Ord a) => [a] -> [Partition a]
equivPartitions = nubBy equiv . partitions
Testing
>>> equivPartitions [1,2,3,4]
[([1,2],[3,4]),([3,2],[1,4]),([3,1],[2,4])]
Note
After using QuickCheck to test the equivalence of this implementation with Daniel's, I found an important difference. Clearly, mine requires an (Ord a) constraint and his does not, and this hints at what the difference would be. In particular, if you give his [0,0,0,0], you will get a list with three copies of ([0,0],[0,0]), whereas mine will give only one copy. Which of these is correct was not specified; Daniel's is natural when considering the two output lists to be ordered sequences (which is what that type is usually considered to be), mine is natural when considering them as sets or bags (which is how this question seemed to be treating them).
Splitting The Difference
It is possible to get from an implementation that requires Ord to one that doesn't, by operating on the positions rather than the values in a list. I came up with this transformation -- an idea which I believe originates with Benjamin Pierce in his work on bidirectional programming.
import Data.Traversable
import Control.Monad.Trans.State
data Labelled a = Labelled { label :: Integer, value :: a }
instance Eq (Labelled a) where
a == b = compare a b == EQ
instance Ord (Labelled a) where
compare a b = compare (label a) (label b)
labels :: (Traversable t) => t a -> t (Labelled a)
labels t = evalState (traverse trav t) 0
where
trav x = state (\i -> i `seq` (Labelled i x, i + 1))
onIndices :: (Traversable t, Functor u)
=> (forall a. Ord a => t a -> u a)
-> forall b. t b -> u b
onIndices f = fmap value . f . labels
Using onIndices on equivPartitions wouldn't speed it up at all, but it would allow it to have the same semantics as Daniel's (up to equiv of the results) without the constraint, and with my more naive and obvious way of expressing it -- and I just thought it was an interesting way to get rid of the constraint.
My own generalized version, added much later, inspired by Will's answer:
import Data.Map (adjust, fromList, toList)
import Data.List (groupBy, sort)
divide xs n evenly = divide' xs (zip [0..] (replicate n [])) where
evenPSize = div (length xs) n
divide' [] result = [result]
divide' (x:xs) result = do
index <- indexes
divide' xs (toList $ adjust (x :) index (fromList result)) where
notEmptyBins = filter (not . null . snd) $ result
partlyFullBins | evenly == "evenly" = map fst . filter ((<evenPSize) . length . snd) $ notEmptyBins
| otherwise = map fst notEmptyBins
indexes = partlyFullBins
++ if any (null . snd) result
then map fst . take 1 . filter (null . snd) $ result
else if null partlyFullBins
then map fst. head . groupBy (\a b -> length (snd a) == length (snd b)) . sort $ result
else []