2
votes

I check other questions on the same error but answers aren't helpful for my problem. For I see no type mis-match!

The error I get is

  Error: operator and operand don't agree [tycon mismatch]
  operator domain: ?.expr list * ?.env
  operand:         expr list * env
  in expression:
    evallist (exprs,ev)

I do not know what is this question mark in type is for or what does it mean! What I can see is that aside from the question mark part, the types are pretty similar. So I really do not get it.

My function is pretty simple

fun evallist(nil, _) = nil
  | evallist (e::exprs, ev) = eval(e,ev):: evallist(exprs,ev)

It recursively evaluate expressions in the environment and creates a list of the result.

It is invoked simply as

vals = evallist(exprs, ev)

Where eval is an expression evaluation function of this type val eval = fn : expr * env -> expr.

Any explanation/ideas on what is the problem? How ?.expr list * ?.env is different than expr list * env?

Thanks you!

This is the minimal code that will reproduce the error.

Updated Code

datatype
   expr = var of string                     
    | num of int                            
    | appfun of expr * expr list          

type env = (string * expr) list         

fun eval (appfun (e, exprs), ev:env) = evallist(exprs, ev)

fun evallist(nil, _) = nil
  | evallist (e::exprs, ev) = 
    let
        val e' = eval(e,ev)
    in
        e':: evallist(exprs,ev)
    end
1
What is eval? Please make this a minimal reproducible example. Also, see this about the question marks: stackoverflow.com/q/23619811/4996248 SML/NJ is known for somewhat cryptic error messagesJohn Coleman
Thanks @JohnColeman for your help. I updated the question. I did look at this question before I post mine, but I do not see it feasible here since I am not redefining/shadowing any of my variables! I feel it is so silly, I am suspecting that it has to do with the type inference, but I am not sure what is going on. Any ideas?Inquirer
Without seeing more code it is hard to say what is happening. The code that you show seems nonproblematic, hence the problem must involve code that you don't show. Can you give a minimal reproducible example? Note: this isn't automatically a dump of all your code, it should be minimal subject to the constraint that it allows others to reproduce the problem.John Coleman
So -- make it minimal. Find the simplest definition of expr and eval which reproduces the problem (e.g. only evaluate + with int literals). It is hard to debug code that you can't even see. As the link minimal reproducible example suggests, the effort in making such an example will often lead you to discover the error on your own. When it doesn't, the effort in making such an example will allow others to help you.John Coleman
Alright @JohnColeman, here is a minimal, complete and verifiable example that would reproduce the error. :) It was good to isolate it but still I can't see where the problem is. I certainly hope you can! Thank you for all your help!Inquirer

1 Answers

2
votes

Your evallist function returns a list, and so does eval. I can get your example to compile if I add the missing and and use list concatenation @ instead of consing:

datatype
   expr = var of string                     
    | num of int                            
    | appfun of expr * expr list          

type env = (string * expr) list         

fun eval (appfun (e, exprs), ev:env) = evallist(exprs, ev)
and evallist(nil, _) = nil
  | evallist (e::exprs, ev) = 
    let
        val e' = eval(e,ev)
    in
        e' @ evallist(exprs,ev)
    end

But I must admit I have no idea if this is what you want because the example has been reduced too far.