Search code examples
pattern-matchingsml

SML error: unresolved flex record


I've just started learning SML and I'm trying to create a function that given an environment and a variable name, returns the int value associated with the variable name. For example if the environment e3 is [("y",100),("x",200)], then calling lookup e3 "y" should return 100. This is what I have so far.

fun lookup nil name = raise NameNotBound name
  | lookup Env name = 
    let
       val e = tl Env;
    in
       if #1(hd Env) = name
       then #2(hd Env)
       else lookup e name
    end;

however when I run this I get the error message "Error: unresolved flex record (need to know the names of ALL the fields in this context) type : {1:string, 2:'Y; 'Z}

I'm honestly not really sure what this error means, I've tried looking it up on the smlnj website and on here but couldn't quite figure it out. Any advice on this would be appreciated.


Solution

  • When you use record/tuple accessors, such as #1 or #2, on a value, SML needs to know the type of that value before hand. Usually that means giving the value an explicit type. So you could give Env a type annotation and that would fix the error.

    Alternatively you could just not use #1 and #2 and instead use pattern matching to access the members of your tuple (which would also avoid your use of the unsafe tl and hd functions). That would look like this:

    | lookup ((headName, headValue) :: tail) name =
    

    and then you could use headName instead of #1(hd Env), headValue instead of #2(hd Env) and tail instead of tl Env.