smlsmlnjml

How to compare and search for an element in a list with a tuple inside a list SML


I want to search in with searchingElements list inside each second element in tuple list and count if there are months in the list inside tuple lists as it shown in the test, I don't know if it should done by recursion, which I have no clue how to use here.

fun number_in_months(months : (int * int * int) list, months2 : (int * int * int) list, 
                      months3 : (int * int * int) list, searchingElements : int list) =
    

  if #2 (hd (tl months)) = (hd searchingElements)
  then
    1 
  else
    0

val test3 = number_in_months ([(2012, 2, 28), (2013, 12, 1), (2011, 3, 31), (2011, 4, 28)], [2, 3, 4]) = 3

I get these 2 errors that I understood later I can't compare between list and tuple list

(fn {1=1,...} => 1) (hd number)
  main.sml:30.2-30.30 Error: operator and operand do not agree [overload - bad instantiation]
  stdIn:2.1-2.5 Error: unbound variable or constructor: fun3

Solution

  • It's really misleading if we read the function code and the test as they both are not type consistent in the very first place.

    If I follow the test function which is

    val test3 = number_in_months ([(2012,2,28),(2013,12,1),(2011,3,31),(2011,4,28)],[2,3,4]) = 3
    

    then the type of number_in_months should be

    val number_in_months = fn: ('a * ''b * 'c) list * ''b list -> int
    

    which is a pair(2-tuple) and the function which is supposed to implement the logic

    fun fun3 (months :(int*int*int) list, months2: (int*int*int) list, months3: 
     (int*int*int) list, searchingElements: int list)
    

    is actually a function with a parameter which is a 4-tuple and a mismatch is evident. Also the parameters months2 and months3 are not used anywhere. Plus, each of the so called months parameters are of type list in themselves. Furthermore, except for the test3 line, there isn't anything which is quite meaningful to come-up with an answer or even a reply.

    However, following the test3 line, I have attempted to write a function that at least gets the thing done and is as follows:

    fun number_in_months (date_triples, months) =
        let
          fun is_second_of_any_triple ele = List.exists (fn (_, x, _) => x = ele)
        in
          List.foldl (fn (curr, acc) => if is_second_of_any_triple curr date_triples then acc + 1 else acc) 0 months
        end