I want to convert list of tuple into tuple of list, and the first list of tuple consist of the first element of original tuple element.
For example
convert [(1,2);(3,4);(5,6)] = ([1;3;5],[2;4;6])
like this.
I tried several times and success to get [1;3;5] by following below code.
let rec convert lst =
match lst with
|[]->[]
|(a,b)::tl->a::(convert tl)
However I have no idea how to get second list element of tuple [2;4;6] and how to merge them in one tuple.
The simplest way is to use the standard library's List.split which does exactly what you want your convert function to do.
Now, if this is part of an exercise, I'm not going to give you the whole solution, but here are a few pointers.
First, you must return a tuple of list. Evidently, the matching of the empty list must return a pair of empty lists.
Now, as for the tricky part, assuming you have (a,b)::tl, getting convert tl first is obviously a thing to do. What can you do if you write in let (tla,tlb) = convert tl? Can you solve it now?
Related
I am new to SML(and functional programming in general) and if anyone could help me with two things I would be glad.
Firstly, I want to read from a file that has the form of a NxM grid where N,M are unknown and store them into an array, either 1d or 2d .
What is a good way to do so?
What I have done so far is read every line as a string and create a string list and then convert every line into a char list.And that brings me to the second question.
Given a char list list A how to create a char list B that is the concatenation of every element in A.I thought foldr could apply here but
foldr concat A
gives me a tycon mismatch error.
Thanks in advance!
Your first question is a bit too vague since a good answer would depend on the structure of the file, which you haven't given. In any event, it seems that you have an answer that would work as soon as your second question is answered.
concat has type string list -> string. You have the tycon mismatch since a char list is not a string.
Instead, the List structure has its own function named concat. It is a polymorphic function of type 'a list list -> 'a list meaning that it can take an arbitrary list of lists and flatten it into a single list. Thus the answer to your second question is simply:
List.concat A
Given string lists [a, b, c] and [d, e] for example,
return the list [ad, bd, cd, ae, be, ce].
Please don't give me an answer, just a point the the right direction for a new learner.
This problem is tricky because you need to traverse two lists. If you write it as one function there are two recursions to keep track of.
One way to approach it is to start with a simpler problem. Say you have a list of strings l and a string s. Can you write a function that makes a new list with s appended to each of the strings in l?
There is a straightforward solution to this simpler problem using List.map. Or you can write an explicitly recursive function.
After that you have only one remaining recursion to figure out, which may be easier.
Update
Now you have your function you can easily write a function that appends a string to all the elements of the first list of strings. The layout would look like this:
let cross_concat list1 list2 =
let concat_string_to_list1 s = concat_string_to_list list1 s in
...
With this definition, you can use List.map again to get the final results (need to concatenate the resulting lists of strings into one list). Or you can use List.fold_right to build up the result as you go. Or you can write your own recursive function.
If you haven't written too many recursive functions, this would be something to think through.
I was wondering if there is a standard function to combine/merge all elements from a list.
I can't seem to find one.
So for example:
combine["abc","def"] should result in ["abcdef"]
Let me Hoogle that for you...
More generally, the concept of "combining", "merging", is captured by the Monoid class1. It has both a mappend function, for combining two values, and mconcat for flattening a whole list.
1Actually, Semigroup is enough... provided the list isn't empty.
I have the following problems where my function take tuple and a list of pair and it should return a tuple but i got the error saying that
a is tuple contains (int*list) and x is list of pairs [(a1,b1).....(an,bn)]
what i want to do is the add two list together lets say I pass in [9;9] [1;0;2] then it should return a [2;0;1], and im using the list.fold_left tail recursion to do it. this is the function i got confuse about,
I pass in the
list.fold_left f (0;[]) (List.combine(List.rev(l1),List.rev(l2))
so a should be a tuple contains (int*list)
x is list of pair
When you use List.fold_left your function gets only one element of the list at a time. It looks to me like your function f is written to expect a list of things as x. But x will be just one pair (if I'm reading your code correctly).
Edit
Since you wrote your f as if x is a list, then when you use List.fold_left with f, you're in essence saying that its argument should be a list of lists. This is what the error message is telling you. If you rewrite f so that x is a pair (which is what you want, I'm pretty sure), this will fix the error.
I've defined a custom list type as part f a homework exercise.
type 'a myType =
| Item of ('a * 'a myType)
| Empty;;
I've already done 'length' and now I need a 'append' function.
My length function:
let length l =
let rec _length n = function
| Empty -> n
| Item(_, next) -> _length (n + 1) next
in _length 0 l;;
But I really don't know how to make the append function.
let append list1 list2 = (* TODO *)
I can't use the list module so I can't use either :: or #.
I guess my comments are getting too lengthy to count as mere comments. I don't really want to answer, I just want to give hints. Otherwise it defeats the purpose.
To repeat my hints:
a. The second parameter will appear unchanged in your result, so you can just
spend your time worrying about the first parameter.
b. You first need to know how to append something to an empty list. I.e., you need
to know what to do when the first parameter is Empty.
c. You next need to know how to break down the non-empty case into a smaller append
problem.
If you don't know how to create an item, then you might start by writing a function that takes (say) an integer and a list of integers and returns a new list with the integer at the front. Here is a function that takes an integer and returns a list containing just that one integer:
let list1 k =
Item (k, Empty)
One way to think of this is that every time Item appears in your code, you're creating a new item. Item is called a constructor because it constructs an item.
I hope this helps.
Your structure is a list, so you should start by defining a value nil that is the empty list, and a function cons head tail, that appends the head element in front of the list tail.
Another advice: sometimes, it helps a lot to start by taking a simple example, and trying to do it manually, i.e. decomposing what you want to do in simple operations that you do yourself. Then, you can generalize and write the code...