0
votes

I have a little experience with SML and I am trying to make a scanner. I am stuck at the folowing CODE. Any help is appreciated.

- fun nextChar nil = NONE
    | nextChar (head::tail) = SOME (head, tail);
- val a = [#"a",#"b",#"d",#"c"];
- val (head, tail) = nextChar a;

I get an error regarding mismatch of pattern and expression return type. Can someone please point out on which pattern can I use to match the expression return type.

Error:

stdIn:7.5-7.28 Error: pattern and expression in val dec don't agree [tycon mismatch]
pattern:    'Z * 'Y
expression:    (char * char list) option
in declaration:
(head,tail) = nextChar a
stdIn:7.5-7.28 Warning: type vars not generalized because of
value restriction are instantiated to dummy types (X1,X2,...)
stdIn:7.5-7.28 Warning: type vars not generalized because of
value restriction are instantiated to dummy types (X1,X2,...)
1
nextChar a returns SOME (#"a", [#"b", #"d", #"c"]), and the type of this value (char × char list) option) will never unify with the type of the pattern in val (head,tail) = ... (being 'a × 'b). If you wrote val SOME (head, tail) = nextChar a, it would work, but it is ill-adviced to deconstruct SOME/NONE in a let-binding, since one pattern will exclude the other and cause a run-time exception. Rather, you should use case-of.Simon Shine

1 Answers

1
votes

As Simon wrote, you are going to need to check the return value of nextChar before you try to use it as a list. You are returning a (char * char list) option not a char * char list. You might want to pattern match on the result to check if it is a SOME tuple and then use it:

val it = case nextChar (a) of
    NONE => defaultChar
  | SOME (head, tail) => head;