[MLton] Bug in signature ascription

Vesa Karvonen vesa.karvonen at cs.helsinki.fi
Wed Feb 7 01:59:26 PST 2007


Quoting "Wesley W. Terpstra" <terpstra at gkec.tu-darmstadt.de>:
[...]
> Let me confirm that I understand what you're saying: Foldr needs  
> enough polymorphism to match the signature FOLD. Unfortunately, the  
> implementation of Foldr required more polymorphism from Fold than  
> FOLD let escape. That's quite a nasty corner case, and I would've  
> never suspected it. Thanks! I just assumed that Vesa's signature was  
> correct since the whole Fold structure is deep magic that I'm  
> terrified to touch. :-)
> 
> In fact, I've already found that Foldr.t needs five type variables,  
> or it breaks variable arity polymorphism. So, I guess the wiki page  
> which describes the signature is wrong. I'll correct the page as soon  
> as I've found the polymorphism that Fold lost.

The Wiki page (http://mlton.org/Fold) is by Stephen.  I did some work
on the Fold technique and you can find the code at:
  http://www.cs.helsinki.fi/u/vkarvone/fold/ .
I promised to update the Wiki pages, but I haven't yet found the time.

It has been a while since I last worked on Fold stuff.  I think that
the FOLD signature for the Fold structure is "correct" and general
enough (although it is not the principal signature).  As you noticed,
I think Foldr (as it stands) needs a different signature.  Note that
Fold evaluates steps (applies the step function to the carried state)
immediately while Foldr delays them to the end.

I believe I designed FoldFnL and FoldFnR structures in an attempt to
make them more alike:

  http://www.cs.helsinki.fi/u/vkarvone/fold/foldfn.sml .

Here is the code for reference:

structure FoldFnL =
  struct
    fun fold d = Fold.fold (id, d)
    fun step0 f = Fold.step0 (fn g => f o g)
    fun step1 f = Fold.step1 (fn (x, g) => f x o g)
  end

structure FoldFnR =
  struct
    fun fold d = Fold.fold (id, d)
    fun step0 f = Fold.step0 (fn g => g o f)
    fun step1 f = Fold.step1 (fn (x, g) => g o f x)
  end

>From the above, SML/NJ gives:

structure FoldFnL :
  sig
    val fold : ('a -> 'b) -> ('c -> 'c,'a,'b,'d) Fold.t
    val step0 : ('a -> 'b) -> ('c -> 'a,'c -> 'b,'d,'e,'f) Fold.step0
    val step1 : ('a -> 'b -> 'c) -> ('a,'d -> 'b,'d -> 'c,'e,'f,'g) Fold.step1
  end

structure FoldFnR :
  sig
    val fold : ('a -> 'b) -> ('c -> 'c,'a,'b,'d) Fold.t
    val step0 : ('a -> 'b) -> ('b -> 'c,'a -> 'c,'d,'e,'f) Fold.step0
    val step1 : ('a -> 'b -> 'c) -> ('a,'c -> 'd,'b -> 'd,'e,'f,'g) Fold.step1
  end

As you can see, the inferred signatures are very similar except
that arrows are reversed.

-Vesa Karvonen



More information about the MLton mailing list