I'm trying to figure this out for some time but I'm not successful.
How is following function (powerset) proceeding in detail, taking the example input argument of [1,2,3]?
Thank you much for help.
fun ps L = foldl (fn (x,tl) => tl # map (fn xs => x::xs) tl) [[]] L;
To use the function correctly, you have to assume there is no duplication in input lists.
The function can be understood as follows:
We start with an accumulator which is a set of sets only consisting of an empty set ([[]]).
In each step, we take every set in the accumulator, add the current element x to them and add these results to the accumulator.
The final result is a set of all possible sets of n elements i.e. powerset.
To be easily express traces, let's create an auxiliary function f
fun f (x, tl) = tl # map (fn xs => x::xs) tl
Now we have a trace for [1, 2, 3]:
ps [1, 2, 3]
~> foldl f [[]] [1, 2, 3] (* Step 1 *)
~> foldl f (f (1, [[]])) [2, 3]
~> foldl f ([[]] # map (fn xs => 1::xs) [[]]) [2, 3]
~> foldl f [[], [1]] [2, 3] (* Step 2 *)
~> foldl f (f (2, [[], [1]])) [3]
~> foldl f ([[], [1]] # map (fn xs => 2::xs) [[], [1]]) [3]
~> foldl f [[], [1], [2], [2, 1]] [3] (* Step 3 *)
~> foldl f (f (3, [[], [1], [2], [2, 1]])) []
~> foldl f ([[], [1], [2], [2, 1]] # map (fn xs => 3::xs) [[], [1], [2], [2, 1]]) []
~> foldl f [[], [1], [2], [2, 1], [3], [3, 1], [3, 2], [3, 2, 1]] [] (* Step 4 *)
~> [[], [1], [2], [2, 1], [3], [3, 1], [3, 2], [3, 2, 1]] (* Final result *)
Related
fun reverse ( [] ) = ( [] )
| reverse (x::xs) = reverse (xs) :: [x]
why my this function of reversing a list is not working
Your function has type 'a list -> 'a list. :: has type 'a -> 'a list -> 'a list. Thus you can't pass the result of calling reverse as the first argument to ::.
You could use # as suggested by JRose because that has type 'a list -> 'a list -> 'a list and will concatenate the two lists but that is inefficient compared to ::. # is O(n). Using it makes reverse have O(n^2) runtime efficiency.
Instead, let's use a tail-recursive helper function to build up an accumulator list in reverse order using ::, then return that. Because :: is O(1), this has O(n) runtime efficiency which is much better.
fun reverse lst =
let
fun aux [] acc = acc
| aux (x::xs) acc = aux xs (x :: acc)
in
aux lst []
end
Consider reversing [1, 2, 3]:
reverse [1, 2, 3]
aux [1, 2, 3] []
aux [2, 3] [1]
aux [3] [2, 1]
aux [] [3, 2, 1]
[3, 2, 1]
Further reading on the efficiency of # and ::. The link talks about OCaml, but the core principles are the same in SML.
How can I get a list of consecutive pairs (tuples) from a list without recursion ?
For example : [1, 2, 3, 4] would be [(1, 2), (2, 3), (3, 4)]
\xs -> zip xs $ tail xs or zip <*> tail.
Consider the list of lists
thisList = [[1], [1, 1], [1, 1, 1]]
how could I multiple thisList so that it would produce another list
anotherList = [[1], [2, 2], [3, 3, 3]]
I have made the function
reps = [1] : map (\ns -> head ns:ns) reps
which produces thisList
Thanks for any help
You could do:
zipWith (\x -> map (const x)) [1..] thisList
Example usage:
Prelude> let thisList = [[1], [1,1], [1,1,1]]
Prelude> zipWith (\x -> map (const x)) [1..] thisList
[[1],[2,2],[3,3,3]]
Or simpler:
zipWith (map . const) [1..] thisList
It's quite easy. zipWith f as bs is equivalent to map (uncurry f) $ zip as bs. So we have:
zip [1..] thisList == [(1, [1]), (2, [1,1,]), (3, [1,1,1])]
Then we apply f to each pair and so:
map (const 1) [1] == [const 1 1] == [1]
map (const 2) [1,1] == [const 2 1, const 2 1] == [2,2]
map (const 3) [1,1,1] == [const 3 1, const 3 1, const 3 1] == [3,3,3]
If you meant that a sublist of length n should be replaced by [n, n, ..., n] of length n, as in:
thisList = [[1, 1], [1], [1], [1, 1, 1]]
result = [[2,2], [1], [1], [3,3,3]]
then you have to change approach:
map (\xs -> let len = length xs in replicate len len) thisList
Example:
Prelude> let thisList = [[1, 1], [1], [1], [1, 1, 1]]
Prelude> map (\xs -> let len = length xs in replicate len len) thisList
[[2,2],[1],[1],[3,3,3]]
I don't know how to exactly express my question in language. Pardon my ambiguous words in the title
My question is:
If you have
a = [[1, 2], [3, 4], [5, 6]....], b = [[1, 3], [4, 8], ....]
How to merge a and b like
[[1,2], [3, 4], [5, 6], [1, 3], [4, 8]....]
in scheme??
I have already tried using car or write a function my self to solve it, but all failed. I was thinking to use (cons a b), but it'll give me [[[1, 2], [3, 4]...], [[1, 3], [4, 8]...]] which is not what I want.
I tried to write a recursive function, but still I'll get the similar trouble as (cons a b)
Thanks!
As pointed out in the comments, you're looking for append. This is how the code in the question would look like in Scheme:
(define a '((1 2) (3 4) (5 6)))
(define b '((1 3) (4 8)))
(append a b)
=> '((1 2) (3 4) (5 6) (1 3) (4 8))
If you want to implement your own version of append it's simple enough:
(define (my-append lst1 lst2)
(if (null? lst1)
lst2
(cons (car lst1)
(my-append (cdr lst1) lst2))))
(my-append a b)
=> '((1 2) (3 4) (5 6) (1 3) (4 8))
I have this mystery function that I'm having trouble understanding:
mystery :: [a] -> [[a]]
mystery [] = [[]]
mystery (x:xs) = sets ++ (map (x:) sets)
where sets = mystery xs
Here are some inputs with results:
mystery [1,2] returns [[],[2],[1],[1,2]]
mystery [1,2,3] returns [[],[3],[2],[2,3],[1],[1,3],[1,2],[1,2,3]]
By looking at the results I can see that its computing all the possible combinations of the numbers in the list, but not all the possible permuations...I think.
The trouble i'm having is actually going through the recursion and understanding how the function is getting those results.
I think I get the start of it --> mapping (1:) onto [2], yielding [1,2], but its at this point that I'm confused how the recursion works, and whether I'm still mapping (1:) or now (2:), and onto what exactly.
If anyone could please help me out by explaining step by step (using one of the examples provided) how this function works (with the map and sets recursion), that would be greatly appreciated!
Thank you!
Haskell will perform what is known as lazy evaluation, meaning it will only work things out as it needs them from left to right (generally). So taking your example of mystery [1, 2], Haskell will do the following:
sets ++ (map (x:) sets)
Which evaluates to:
mystery (2:[]) ++ (map (1:) sets)
At this point, we're calling mystery (2:[])
mystery ([]) ++ (map (2:) sets) ++ (map (1:) sets)
mystery ([]) will return an empty list of lists
[[]] ++ (map (2:) sets) ++ (map (1:) sets)
[[]] ++ (map (2:) mystery []) ++ (map (1:) sets)
So now Haskell will try to apply the function (2:) on a list containing an empty list
[[]] ++ (2:[[]]) ++ (map (1:) sets)
[[]] ++ [[2]] ++ (map (1:) sets)
[[], [2]] ++ (map (1:) sets)
This is where things get a little more confusing.
[[], [2]] ++ (map (1:) mystery (2:[]))
That last sets will evaluate mystery (2:[])
[[], [2]] ++ (map (1:) (sets ++ (map (2:) sets)))
[[], [2]] ++ (map (1:) (mystery [] ++ (map (2:) sets))
[[], [2]] ++ (map (1:) ([[]] ++ (map (2:) mystery []))
[[], [2]] ++ (map (1:) ([[]] ++ (2:[[]]))
[[], [2]] ++ (map (1:) ([[]] ++ [[2]])
Now (1:) will be applied to a list which contains an empty list, and a list containing the 2:
[[], [2]] ++ (map (1:) ++ [[], [2]])
[[], [2]] ++ [[1], [1, 2]]
[[], [2], [1], [1, 2]]
The real meat of the operation is in those last two sections. Haskell creates a list like [[], [2]] and then appends one to the head of each list to form [[1], [1, 2]].
your mystery function is computes the power set of its input.