[Haskell-cafe] Type Directed Name Resolution

Richard O'Keefe ok at cs.otago.ac.nz
Thu Nov 11 17:07:40 EST 2010


On 11/11/2010, at 10:33 PM, Gábor Lehel wrote:

> I would have TDNR apply only in cases where:
...
> - The ambiguity can be resolved by looking at the type of the first
> (taking currying into account, only) parameter of each function and,
> looking at the type constructors from the outside in, comparing only
> type constructors which are concrete types, rather than type variables
> (with or without constraints).

This just feels so wrong.  One of the joys of types in Haskell and of
overloading in Ada is that it depends on *all* the arguments of a
function *and* the result.

I note that record field overloading can be put in a language without
providing ad hoc polymorphism for any other functions.  A little ML:
Given 

  type t1 = {a: int, b: string};
  type t2 = {a: string, b: int};
  val x1 : t1 = {a = 1,  b = "2"};
  val x2 : t2 = {b = 2, a = "1"};

this interaction followed:

- (#a x1, #a x2, #b x1, #b x2);
val it = (1,"1","2",2) : int * string * string * int

Here we had
    #a : t1 -> int          #b : t1 -> string
    #a : t2 -> string       #b : t2 -> int

The consequence is that when I see 
	val N = #capacity derived ()
I don't know what capacity means for sure, but I *do* know that it is
a record field, so I have some idea what to look for.
It turns out that there are four possibilities but for two of them
() would not be a legal argument, so there are only two possibilities.

I note that there is a reason for having quite a few records in a
module with many shared field names at different types, which I had
not thought of.  That is the practice of passing a record as a
function's sole argument in order to get the effect of keyword
arguments, fairly popular in SML:

      val max_flow : {
	     graph    : ('n,'e,'g) Graph.graph,
             s        : Graph.node_id,
             t        : Graph.node_id,
             capacity : 'e Graph.edge -> Num.elem,
             flows    : 'e Graph.edge * Num.elem -> unit
          } -> Num.elem
          
      val min_cost_max_flow : {
             graph    : ('n,'e,'g) Graph.graph,
             s        : Graph.node_id,
             t        : Graph.node_id,
             capacity : 'e Graph.edge -> Num.elem,
             cost     : 'e Graph.edge -> Num.elem,
             flows    : 'e Graph.edge * Num.elem -> unit
          } -> Num.elem

There is no intention here to have lots of values of these record types.
They are anonymous, after all.  This case needs to be considered
separately from other cases.

> 
> And, in any case, as a language extension nobody would be forced to
> use it if they don't like it.

Wrong.

They would not be forced to use it in their own code,
but they *WOULD* be forced to read it in other people's code.
(Why so much focus on the writers and so little on the readers?)



More information about the Haskell-Cafe mailing list