anchor.diff:  	Type ->
   	    {typed,As,Body,Type}
       end;
  +infer_expr(Env,{tuple,As,Cpts}) ->
  +    NewCpts = [infer_expr(Env,C) || C <- Cpts],
  +    CptTypes = [T || {typed,_,_,T} <- NewCpts],
  +    {typed,As,{tuple,As,NewCpts},{tuple_t,As,CptTypes}};
  +infer_expr(Env,{list,As,Elems}) ->
  +    NewElems = [infer_expr(Env,X) || X <- Elems],
  +    ElemType = fresh_uvar(As),
  +    [unify(ElemType,T) || {typed,_,_,T} <- NewElems],
  +    {typed,As,{list,As,NewElems},{app_t,As,{id,As,"list"},[ElemType]}};    
   infer_expr(Env,{app,As=[_,{format,infix}],Op,Args}) ->
       TypedArgs = [infer_expr(Env,A) || A <- Args],
       ArgTypes = [T || {typed,_,_,T} <- TypedArgs],
  
positive.code: 
  
  cannot_unify(A,B) ->
      io:format("Cannot unify ~s (from line ~p)\n"
  	      "         and ~s (from line ~p)\n",
  	      [pp(A),line_number(A),pp(B),line_number(B)]).
  
  line_number(T) when is_tuple(T) ->
      proplists:get_value(line,element(2,T)).
  
  pp({type_sig,As,B}) ->
      ["(",pp(As),") => ",pp(B)];
  pp([T]) ->
      pp(T);
  pp({id,_,Name}) ->
      Name;
  pp({tvar,_,Name}) ->
      Name.
  
  
negative.code:     true;
  unify1({fun_t,_,Args1,Result1},{fun_t,_,Args2,Result2}) ->
      unify(Args1,Args2) andalso unify(Result1,Result2);
  unify1({app_t,_,{id,_,F},Args1},{app_t,_,{id,_,F},Args2}) 
    when length(Args1)==length(Args2) ->
      unify(Args1,Args2);
  unify1({tuple_t,_,As},{tuple_t,_,Bs}) 
    when length(As)==length(Bs) ->
      unify(As,Bs);
  unify1(A,B) ->
      cannot_unify(A,B),
      false.
  