Folks,

I'm trying to write a shuffle function in TR, composed of a
"Cutter" function and a "Riffler" function. I start with a
few types and implementations for a cutter and a riffler.

The shuffler is basically (riffle (cut deck)):
----------------------------------------------------------
#lang typed/racket

(define-type (Cutter A) ((Listof A) -> (Values (Listof A) (Listof A))))
(define-type (Riffler A) ((Listof A) (Listof A) -> (Listof A)))
(define-type (Shuffler A) ((Listof A) -> (Listof A)))

(: overhand-cutter Cutter)
(define (overhand-cutter l)
  (split-at l (random (length l))))

(: overhand-riffler Riffler)
(define (overhand-riffler p1 p2)
  (append p2 p1))

(: uncomposed-o/h-shuffler Shuffler)
(define (uncomposed-o/h-shuffler deck)
  (call-with-values (λ () (overhand-cutter deck))
                    overhand-riffler))
----------------------------------------------------------

uncomposed-o/h-shuffler behaves (typewise), as I'd expect:

> (:print-type uncomposed-o/h-shuffler)
Shuffler
> ((inst uncomposed-o/h-shuffler Integer) '(1 2 3))
- : (Listof Integer)
(2 3 1)
> ((inst uncomposed-o/h-shuffler Symbol) '(1 2 3))
[X] Type Checker: type mismatch
  expected: (Listof Symbol)
  given: (List One Positive-Byte Positive-Byte) in: (quote (1 2 3))

Now I want to factor that composition into a function that takes a
cutter, a riffler and produces a shuffler:

----------------------------------------------------------
(: shuffler-composer (All (A) (Cutter A) (Riffler A) -> (Shuffler A)))
(define ((shuffler-composer cut riffle) deck)
  (call-with-values (λ () (cut deck)) riffle))

;; Note the annotation is currently commented out
;; (: composed-overhand-shuffler (All (A) (Shuffler A)))
(define composed-overhand-shuffler
  (shuffler-composer
   overhand-cutter
   overhand-riffler))
----------------------------------------------------------

composed-overhand-shuffler is of type:
> (:print-type composed-overhand-shuffler)
(-> (Listof Any) (Listof Any))

Which is not a shuffler (it doesn't undertake to return the same type
of list as its input).

Uncommenting the ":" annotation above the function declaration moves
the problem to be a syntax error...
----------------------------------------------------------
[X] shuffle.rkt:27:2: Type Checker: Polymorphic function `shuffler-composer' could not be applied to arguments:
Argument 1:
  Expected: (-> (Listof A) (values (Listof A) (Listof A)))
  Given:    Cutter
Argument 2:
  Expected: (-> (Listof A) (Listof A) (Listof A))
  Given:    Riffler

Result type:     (-> (Listof A) (Listof A))
Expected result: Shuffler
 in: (shuffler-composer overhand-cutter overhand-riffler)
----------------------------------------------------------

I have tried everything (with the exception of the right thing) to mould
this function to my will:
- used longhand types rather than the define-types Riffler, Cutter and
  Shuffler
- All'ed, inst'ed, ann'ed and cast'ed everywhere
- used various approached to the implementation. Here we
  have call-with-values, but I have used define-values (with/without
  annotations), explicit and automatic currying -- the works.

Everything seems to be being done; except the annotation of the return
from shuffler-composer.

What am I missing?
Do I not understand something?
Am I not hinting TR quite well enough?
Is there a bug in TR stopping me?
Is this a fundamental limitation of TR's type system?

Please could someone help.

Thanks.

Tim

---
This email has been checked for viruses by Avast antivirus software.
http://www.avast.com

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to