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
Related
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?
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 understand that lists are implemented as singly linked so they don't really have a constant structure that you can pin a length on, but each node should know how many nodes till the last element right? There isn't a way to add a node to some existing list and for that node not to be able to determine the length of the list it represents in constant time provided that the existing nodes already have that info.
I can understand why that wouldn't work in Haskell, for example, due to lazyness, but as far as I know F# lists aren't lazy. So, is the problem just in the extra memory overhead?
Seems to me like typical memory vs time performance consideration.
If standard f# list had the implementation You suggest, then it would need much more place in memory (consider one million long list of bools). And everyone using such list would have to deal with it. There would be no simple way to opt out of this other than writing completely new implementation of list.
On the other hand, it seems to be fairly simple to create a new type that would store length of succeeding list with each element basing on F# List. You can implement it on Your own if You need it. Those, who don't need it will use standard implementation.
I don't often find myself needing to know the length of the list, it's not like you need it to exit a for loop like you would with arrays in imperative languages.
For those rare cases when you really need to know the length asap, you can go with Carsten König's suggestion from a comment and make your 'a list into a ('a * int) list, where each node keeps the length of the tail as a tuple element.
Then you can have something like this:
let push lst e =
match lst with
| (_, c)::_ -> (e, c + 1) :: lst
| [] -> [e, 0]
and length and pop functions to match.
For all the other cases I'd call it a premature optimization.
let's say we have a list of elements:
[(a,b); (c,d); (e,f)]
What function would check if element (lets say A, where A=(x,y)) is in the list or not?
Use List.mem to do the search for a match.
let a = (3,4)
List.mem a [(1,2); (3,4); (5,6)]
You can also use List.memq if you want to check if the two items both reference the same entity in memory.
Here's a hint on how to write this yourself. The natural way to to process a list is to initially look at the first element, then check the remainder of the list recursively until you have an empty list. For this problem, you could state the algorithm in English as follows:
If the list is empty then the item is not in the list,
else if the first list element equals the item then it is in,
else it is the answer to (Is the item in the remainder of the list?)
Now you just need to translate this into OCaml code (using a recursive function).
In general, if you can describe what you want to do in terms of smaller or simpler parts of the problem, then writing the recursive code is straightforward (although you have to be careful the base cases are correct). When using a list or tree-structured data the way to decompose the problem is usually obvious.
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...