JoshieSimmons
JoshieSimmons

Reputation: 2791

SML Pattern matching throwing "types of rules don't agree [tycon mismatch]" error

fun sample(list_of_str_lists, s) =
    case list_of_str_lists of
           [] => []
        | x::[] => case (all_except_option(s, x)) of
                        SOME lst => lst
                      | NONE => []
        | x::xs' => case (all_except_option(s, x)) of
                        SOME lst => lst @ sample(xs', s)
                      | NONE => [] @ sample(xs', s)

It uses a helper function that takes a list of strings and returns all elements in that list in an list option if there is a matching string in that list (again, excluding the matching string). So the helper function will take a list ["a", "b", "c"] and a string "a" and if it matches "a", will return an option containing ["b", “c”].

My problem is in sample in the last pattern matching branch. It throws the error

earlier rule(s): 'Z list option -> 'Z list
  this rule: string list list -> string list
  in rule:
    :: (x,xs') =>
      (case (all_except_option (s,x))
        of SOME lst => lst @ sample <exp>
         | NONE => nil @ sample <exp>

but I don’t understand why, because the pattern I’m trying to match calls for SOME lst but it’s describing it as string list list. What’s going on?

Upvotes: 2

Views: 1433

Answers (1)

waldrumpus
waldrumpus

Reputation: 2590

This is a syntax issue due to the nested case expressions. The parser assumes that the case | x::xs' => ... is a continuation of the ongoing case expression case (all_except_option(s, x)) of ... since it has no way of telling it's actually meant to belong to the enclosing expression case list_of_str_lists of ....

If you enclose the inner case expressions in parentheses, the function definition will parse.

fun sample(list_of_str_lists, s) =
  case list_of_str_lists of
    []     => []
  | x::[]  => (case (all_except_option(s, x)) of
                 SOME lst => lst
               | NONE     => [])
  | x::xs' => (case (all_except_option(s, x)) of
                  SOME lst => lst @ sample(xs', s)
                | NONE     => [] @ sample(xs', s))

Upvotes: 5

Related Questions