Hello I'm new at SML and I've been trying to write a function that gets as a parameter a list (in my case the list prussia) which has tuples with two ints and a string, my function has to create a list with all the years that appear in the list without repetitions (2nd element of each tuple of the list). I have to do it creating two functions (append_if_new takes a year of the list and adds it in the list, it works) and year has to do it for all the tuples in the list, i tried it using foldl but i get a tycon mismatch.
Pd. to do it i have to use the function map, filter or fold and i can move append_if_new functionalities to the year function. I think the error is in the fold call where the function i pass as parameter is not the type of function i should pass but I'm not sure what is the problem. Thanks
val prussia =
[(0,1875,"G"),(2,1876,"G"),(2,1877,"G"),(1,1878,"G"),(0,1879,"G"),
(0,1880,"G"),(1,1881,"G"),(1,1882,"G"),(0,1883,"G"),(3,1884,"G"),
(0,1885,"G"),(2,1886,"G"),...] : (int * int * string) list
fun append_if_new (lista:(int*int*string)list): int list =
let
val lista2 = []
val x = hd lista
val z = #2x
in
if (List.exists (fn y => y = z) lista2)
then lista2
else lista2@[z]
end
fun years (lista:(int*int*string)list): int list =
List.foldl append_if_new 0 lista
create a list with all the years that appear in the list without repetitions
(2nd element of each tuple of the list)
You can create a list with repetitions using map
and filter duplicates afterwards:
fun year_of (_, year, _) = year
fun member (y, xs) = List.exists (fn x => y = x) xs
fun nub [] = []
| nub (x::xs) = if member (x, xs)
then nub xs
else x :: nub xs
fun years records = nub (map year_of records)
Here nub
has an asymptotic running-time complexity of O(n²), which is bad and unnecessary. You can also go straight ahead and fold the list such that you never insert the duplicates to begin with:
fun member (y, xs) = List.exists (fn x => y = x) xs
fun years records =
let
fun insert ((_, year, _), years) =
if member (year, years)
then years
else year :: years
in
foldr insert [] records
end
but the asymptotic running time is the same, and it is slightly more obscure to read. If you want to filter duplicates in an efficient way, you have to use a more efficient data structure to manage duplicates, like a tree-based set or similar. In Haskell, this is the difference between nub
and nubOrd
.