type-scheme.scm 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey
  3. ; Type schemes
  4. (define-record-type type-scheme :type-scheme
  5. (make-type-scheme type free-uvars)
  6. type-scheme?
  7. (type type-scheme-type) ; a type
  8. (free-uvars type-scheme-free-uvars)) ; uvars that are free
  9. (define-record-discloser :type-scheme
  10. (lambda (type-scheme)
  11. (list 'type-scheme
  12. (map uvar-id (type-scheme-free-uvars type-scheme))
  13. (type-scheme-type type-scheme))))
  14. ; If TYPE has any variables bound at DEPTH this returns a type scheme making
  15. ; those variables polymorphic; otherwise TYPE is returned.
  16. ; Would like to do limited finalizing of uvars, but can't.
  17. ; Consider (lambda (g x) (tuple (g 3) (g x) x))
  18. ; (a -> b) -> c -> [d, e, f] with
  19. ; a > int8, d > b, a > c, e > b, f > c
  20. ; No polymorphism, and no simplification without restricting someone
  21. ; But consider NOT a ->b, bool > a, b > bool
  22. ; It could just as well be bool -> bool.
  23. ; Simplification okay on variables that are not used inside other types?
  24. (define *free-uvars* '())
  25. (define (schemify-type type depth)
  26. (set! *free-uvars* '())
  27. (let* ((type (find-free-uvars type depth))
  28. (free-uvars *free-uvars*))
  29. (set! *free-uvars* '()) ; drop pointers
  30. (for-each (lambda (uvar)
  31. (set-uvar-place! uvar #f))
  32. free-uvars)
  33. (if (not (null? free-uvars))
  34. (make-type-scheme type free-uvars)
  35. type)))
  36. (define (find-free-uvars type depth)
  37. (let label ((type type))
  38. (cond ((other-type? type)
  39. (make-other-type (other-type-kind type)
  40. (map label
  41. (other-type-subtypes type))))
  42. ((not (uvar? type))
  43. type)
  44. ((uvar-binding type)
  45. => label)
  46. ((and (not (uvar-place type))
  47. (<= depth (uvar-depth type)))
  48. (set-uvar-place! type type)
  49. (set! *free-uvars* (cons type *free-uvars*))
  50. type)
  51. (else
  52. type))))
  53. ; Instantiate SCHEME at DEPTH.
  54. ;
  55. ; New sequence:
  56. ; (instantiate-type-scheme scheme depth)
  57. ; ... elide bindings in new copy ...
  58. ; (clean-type-scheme scheme)
  59. (define (instantiate-type-scheme scheme depth . maybe-thunk)
  60. (instantiate-type-scheme! scheme depth)
  61. (let ((type (copy-type (type-scheme-type scheme))))
  62. (if (not (null? maybe-thunk))
  63. ((car maybe-thunk)))
  64. (clean-type-scheme! scheme)
  65. type))
  66. (define (instantiate-type-scheme! scheme depth)
  67. (let ((uid (unique-id)))
  68. (for-each (lambda (uvar)
  69. (set-uvar-place!
  70. uvar
  71. (make-uvar (uvar-prefix uvar) depth uid)))
  72. (type-scheme-free-uvars scheme))))
  73. (define (clean-type-scheme! scheme)
  74. (for-each (lambda (uvar)
  75. (set-uvar-place! uvar #f))
  76. (type-scheme-free-uvars scheme)))
  77. (define (copy-type type)
  78. (cond ((other-type? type)
  79. (make-other-type (other-type-kind type)
  80. (map copy-type
  81. (other-type-subtypes type))))
  82. ((not (uvar? type))
  83. type)
  84. ((uvar-place type)
  85. => identity)
  86. ((uvar-binding type)
  87. => copy-type)
  88. (else
  89. type)))