S. Nabil
S. Nabil

Reputation: 319

SML operator and operand don't agree [tycon mismatch]

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

Upvotes: 2

Views: 602

Answers (1)

Florian Weimer
Florian Weimer

Reputation: 33694

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.

Upvotes: 2

Related Questions