more docs and cleanups

This commit is contained in:
Sam Caldwell 2021-05-05 12:52:07 -04:00
parent 4f6089c805
commit 690f9e65a8
7 changed files with 207 additions and 101 deletions

View File

@ -172,6 +172,13 @@ See @racket[→].
@section{User Defined Types}
@defform*[[(define-type-alias id type)
(define-type-alias (ty-cons-id arg-id ...) type)]]{
Define @racket[id] to be the same as @racket[type], or create a type constructor
@racket[(ty-cons-id ty ...)] whose meaning is @racket[type] with references to
@racket[arg-id ...] replaced by @racket[ty ...].
}
@defform[(define-constructor (ctor-id slot-id ...)
maybe-type-ctor
maybe-alias ...)
@ -456,7 +463,8 @@ Instantiates the type variables @racket[X ...] with @racket[type ...], where
(opt-res-ty (code:line)
(code:line arr res-type))
(arr (code:line →) (code:line ->))]]{
Define a constant or a (potentially polymorphic) function.
Define a constant or a (potentially polymorphic) function. Note that the
function name @racket[id] is @emph{not} bound in the body.
}
@defform[(define-tuple (id ...) expr)]{
@ -489,13 +497,13 @@ Constructs a tuple of arbitrary arity.
Extract the @racket[i]th element of a @racket[tuple].
}
@defthing[unit Unit #:value (tuple)]
@defform[(error format-expr arg-expr ...)]{
Raises an exception using @racket[format-expr] as a format string together with
@racket[arg-expr ...].
}
@defthing[unit Unit #:value (tuple)]
@deftogether[(
@defthing[+ (→fn Int Int Int)]
@defthing[- (→fn Int Int Int)]
@ -533,6 +541,43 @@ Raises an exception using @racket[format-expr] as a format string together with
Primitive operations imported from Racket.
}
@defform[#:literals (:)
(for/fold ([acc-id maybe-:ty acc-expr] ...+)
(for-clause ...)
body-expr ...+)
#:grammar
[(maybe-:ty (code:line)
(code:line : acc-type))
(for-clause (code:line [id seq-expr])
(code:line [id : type seq-expr])
(code:line [(k-id v-id) hash-expr])
(code:line #:when test-expr)
(code:line #:unless test-expr)
(code:line #:break test-expr))]]{
Similar to Racket's @racket[racket:for/fold].
When more than one @racket[acc-id] is used, the body of the loop must evaluate
to a @racket[tuple] with one value for each accumulator, with the final tuple
also being the result of the entire expression.
Each @racket[seq-expr] should be of type @racket[Sequence], though expressions
of type @racket[List] and @racket[Set] are automatically converted.
}
@deftogether[(
@defform[(for/list (for-clause ...) body ...+)]
@defform[(for/set (for-clause ...) body ...+)]
@defform[(for/sum (for-clause ...) body ...+)]
@defform[(for (for-clause ...) body ...+)]
@defform[(for/first (for-clause ...) body ...+)]
)]{
Like their Racket counterparts. See @racket[for/fold] for the description of
@racket[for-clause].
Unlike @racket[racket:for/first], @racket[for/first] returns a @racket[Maybe]
value to indicate success/failure.
}
@section{Require & Provide}
@defform[(struct-out ctor-id)]{
@ -550,6 +595,9 @@ Primitive operations imported from Racket.
(opaque (code:line =) (code:line >) (code:line >=))]]{
Import and assign types to bindings from outside Typed Syndicate.
Note that @emph{unlike} Typed Racket, Typed Syndicate does not attach contracts
to imported bindings.
An @racket[#:opaque] declaration defines a type @racket[type-name] (or, in the
@racket[#:arity] case, a type constructor) that may be used to describe imports
but otherwise has no other operations.
@ -591,8 +639,138 @@ Constructor for a broadcast message.
@subsection{Lists}
@defform[(List type)]{
The type for @racket[cons] lists whose elements are of type @racket[type].
}
@deftogether[(
@defthing[empty (List ⊥)]
@defthing[empty? (∀ (X) (→fn (List X) Bool))]
@defthing[cons (∀ (X) (→fn X (List X) (List X)))]
@defthing[cons? (∀ (X) (→fn X (List X) Bool))]
@defthing[first (∀ (X) (→fn (List X) X))]
@defthing[second (∀ (X) (→fn (List X) X))]
@defthing[rest (∀ (X) (→fn (List X) (List X)))]
@defthing[member? (∀ (X) (→fn X (List X) Bool))]
@defthing[reverse (∀ (X) (→fn (List X) (List X)))]
@defthing[partition (∀ (X) (→fn (List X) (→fn X Bool) (List X)))]
@defthing[map (∀ (X Y) (→fn (→fn X Y) (List X) (List Y)))]
@defthing[argmax (∀ (X) (→fn (→fn X Int) (List X) X))]
@defthing[argmin (∀ (X) (→fn (→fn X Int) (List X) X))]
@defthing[remove (∀ (X) (→fn X (List X) (List X)))]
@defthing[length (∀ (X) (→fn (List X) Int))]
@defform[(list e ...)]
)]{
Like their Racket counterparts.
}
@subsection{Sets}
@defform[(Set type)]{
The type for sets whose elements are of type @racket[type].
}
@deftogether[(
@defform[(set e ...)]
@defform[(set-union st ...+)]
@defform[(set-intersect st ...+)]
@defform[(set-subtract st ...+)]
@defthing[set-first (∀ (X) (→fn (Set X) X))]
@defthing[set-empty? (∀ (X) (→fn (Set X) Bool))]
@defthing[set-count (∀ (X) (→fn (Set X) Int))]
@defthing[set-add (∀ (X) (→fn (Set X) X (Set X)))]
@defthing[set-remove (∀ (X) (→fn (Set X) X (Set X)))]
@defthing[set-member? (∀ (X) (→fn (Set X) X Bool))]
@defthing[list->set (∀ (X) (→fn (List X) (Set X)))]
@defthing[set->list (∀ (X) (→fn (Set X) (List X)))]
)]{
Like their Racket counterparts.
}
@subsection{Hashes}
@defform[(Hash key-type value-type)]{
The type for key/value hash tables.
}
@deftogether[(
@defform[(hash key val ... ...)]
@defthing[hash-set (∀ (K V) (→fn (Hash K V) K V (Hash K V)))]
@defthing[hash-ref (∀ (K V) (→fn (Hash K V) K V))]
@defthing[hash-ref/failure (∀ (K V) (→fn (Hash K V) K V V))]
@defthing[hash-empty? (∀ (K V) (→fn (Hash K V) Bool))]
@defthing[hash-has-key? (∀ (K V) (→fn (Hash K V) K Bool))]
@defthing[hash-count (∀ (K V) (→fn (Hash K V) Int))]
@defthing[hash-update (∀ (K V) (→fn (Hash K V) K (→fn V V) (Hash K V)))]
@defthing[hash-update/failure (∀ (K V) (→fn (Hash K V) K (→fn V V) V (Hash K V)))]
@defthing[hash-remove (∀ (K V) (→fn (Hash K V) K (Hash K V)))]
@defthing[hash-map (∀ (K V R) (→fn (Hash K V) (→fn K V R) (List R)))]
@defthing[hash-keys (∀ (K V) (→fn (Hash K V) (List K)))]
@defthing[hash-values (∀ (K V) (→fn (Hash K V) (List V)))]
@defthing[hash-union (∀ (K1 V1 K2 V2) (→fn (Hash K1 V1) (Hash K2 V2) (Hash (U K1 K2) (U V1 V2))))]
@defthing[hash-union/combine (∀ (K V) (→fn (Hash K V) (Hash K V) (→fn V V V) (Hash K V)))]
@defthing[hash-keys-subset? (∀ (K1 V1 K2 V2) (→fn (Hash K1 V1) (Hash K2 V2) Bool))]
)]{
Like their Racket counterparts. The /failure and /combine suffixes are in place
of keyword arguments, which Typed Syndicate does not presently support.
}
@subsection{Sequences}
@defform[(Sequence type)]{
The type for a sequence of @racket[type] values.
}
@deftogether[(
@defthing[empty-sequence (Sequence ⊥)]
@defthing[sequence->list (∀ (X) (→fn (Sequence X) (List X)))]
@defthing[sequence-length (∀ (X) (→fn (Sequence X) Int))]
@defthing[sequence-ref (∀ (X) (→fn (Sequence X) Int Int))]
@defthing[sequence-tail (∀ (X) (→fn (Sequence X) Int (Sequence X)))]
@defthing[sequence-append (∀ (X) (→fn (Sequence X) (Sequence X) (Sequence X)))]
@defthing[sequence-map (∀ (A B) (→fn (→fn A B) (Sequence A) (Sequence B)))]
@defthing[sequence-andmap (∀ (X) (→fn (→fn X Bool) (Sequence X) Bool))]
@defthing[sequence-ormap (∀ (X) (→fn (→fn X Bool) (Sequence X) Bool))]
@defthing[sequence-fold (∀ (A B) (→fn (→fn A B A) (Sequence B) A))]
@defthing[sequence-count (∀ (X) (→fn (→fn X Bool) (Sequence X) Int))]
@defthing[sequence-filter (∀ (X) (→fn (→fn X Bool) (Sequence X) (Sequence X)))]
@defthing[sequence-add-between (∀ (X) (→fn (Sequence X) X (Sequence X)))]
@defthing[in-list (∀ (X) (→fn (List X) (Sequence X)))]
@defthing[in-hash-keys (∀ (K V) (→fn (Hash K V) (Sequence K)))]
@defthing[in-hash-values (∀ (K V) (→fn (Hash K V) (Sequence V)))]
@defthing[in-range (→fn Int (Sequence Int))]
@defthing[in-set (∀ (X) (→fn (Set X) (Sequence X)))]
)]{
Like their Racket counterparts.
}
@subsection{Maybe}
@deftogether[(
@defidform[None]
@defthing[none None]
@defstruct[some ([v any?]) #:omit-constructor]
@defform[(Some type)]
@defform[(Maybe type)]
)]{
@racket[(Maybe type)] is an alias for @racket[(U None (Some type))].
}
@subsection{Either}
@deftogether[(
@defstruct[left ([v any?]) #:omit-constructor]
@defform[(Left type)]
@defstruct[right ([v any?]) #:omit-constructor]
@defform[(Right type)]
@defform[(Either left-type right-type)]
)]{
@racket[(Either left-type right-type)] is an alias for @racket[(U (Left
left-type) (Right right-type))].
}
@defthing[partition/either (∀ (X Y Z) (→fn (List X) (→fn X (Either Y Z)) (Tuple (List Y) (List Z))))]{
Partition a list based on a function that returns an @racket[Either] value.
}
@section{Behavioral Checking}

View File

@ -19,13 +19,8 @@
(U (Left A)
(Right B)))
(define ( (X) (f [x : X] -> X))
x)
(define ( (X Y Z) (partition/either [xs : (List X)]
[pred : (→fn X (U (Left Y)
(Right Z)))]
[pred : (→fn X (Either Y Z))]
-> (Tuple (List Y) (List Z))))
(for/fold ([lefts (List Y) (list)]
[rights (List Z) (list)])

View File

@ -5,9 +5,7 @@
for/list
for/set
for/sum
for/first
in-hash-values
in-hash-keys)
for/first)
(require "core-types.rkt")
(require "sequence.rkt")
@ -257,14 +255,3 @@
( ν-ep (τ-ep ...))
( ν-s (τ-s ...))
( ν-f (τ-f ...))])
(define-typed-syntax (in-hash-values h)
[ h h- ( : (~Hash K V))]
--------------------
[ (#%app- in-hash-values- h-) ( : (Sequence V))])
(define-typed-syntax (in-hash-keys h)
[ h h- ( : (~Hash K V))]
--------------------
[ (#%app- in-hash-keys- h-) ( : (Sequence K))])

View File

@ -45,10 +45,8 @@
#;[make-hash : ( (K V) (→fn (List (ConsPair K V)) (Hash K V)))]
[hash-set : ( (K V) (→fn (Hash K V) K V (Hash K V)))]
[hash-ref : ( (K V) (→fn (Hash K V) K V))]
;; TODO hash-ref/failure
[hash-has-key? : ( (K V) (→fn (Hash K V) K Bool))]
[hash-update : ( (K V) (→fn (Hash K V) K (→fn V V) (Hash K V)))]
;; TODO hash-update/failure
[hash-remove : ( (K V) (→fn (Hash K V) K (Hash K V)))]
[hash-map : ( (K V R) (→fn (Hash K V) (→fn K V R) (List R)))]
[hash-keys : ( (K V) (→fn (Hash K V) (List K)))]
@ -61,7 +59,6 @@
(require/typed racket/hash
[hash-union : ( (K1 V1 K2 V2) (→fn (Hash K1 V1) (Hash K2 V2) (Hash (U K1 K2) (U V1 V2))))]
;; TODO - hash-union with #:combine
)
(define- (hash-ref/failure- h k err)

View File

@ -3,12 +3,14 @@
(provide List
(for-syntax ~List)
list
(typed-out [[cons- : ( (X) (→fn X (List X) (List X)))] cons]
(typed-out [[empty- : (List )] empty]
[[empty?- : ( (X) (→fn X (List X) Bool))] empty?]
[[cons- : ( (X) (→fn X (List X) (List X)))] cons]
[[cons?- : ( (X) (→fn X (List X) Bool))] cons?]
[[first- : ( (X) (→fn (List X) X))] first]
[[second- : ( (X) (→fn (List X) X))] second]
[[rest- : ( (X) (→fn (List X) (List X)))] rest]
[[member?- ( (X) (→fn X (List X) Bool))] member?]
[[empty?- ( (X) (→fn (List X) Bool))] empty?]
[[reverse- ( (X) (→fn (List X) (List X)))] reverse]
[[partition- ( (X) (→fn (List X) (→fn X Bool) (List X)))] partition]
[[map- ( (X Y) (→fn (→fn X Y) (List X) (List Y)))] map]

View File

@ -17,12 +17,15 @@
sequence-add-between
in-list
in-set
in-hash-keys
in-hash-values
in-range
)
(require "core-types.rkt")
(require (only-in "list.rkt" List))
(require (only-in "set.rkt" Set))
(require (only-in "hash.rkt" Hash))
(require (only-in "prim.rkt" Int Bool))
#;(require (postfix-in - racket/sequence))
@ -50,25 +53,8 @@
(require/typed racket/base
[in-list : ( (X) (→fn (List X) (Sequence X)))]
[in-hash-keys : ( (K V) (→fn (Hash K V) (Sequence K)))]
[in-hash-values : ( (K V) (→fn (Hash K V) (Sequence V)))]
[in-range : (→fn Int (Sequence Int))])
(require/typed racket/set
[in-set : ( (X) (→fn (Set X) (Sequence X)))])
#;(define-typed-syntax empty-sequence
[_
--------------------
[ empty-sequence- ( : (Sequence (U)))]])
;; er, this is making everything a macro, as opposed to a procedure...
;; think I ought to add polymorphous first :\
#;(define-typed-syntax (sequence->list s)
[ s s- ( : (~Sequence τ))]
#:fail-unless (pure? #'s-)
------------------------------
[ (sequence->list- s-) ( : (List τ))])
#;(define-typed-syntax (sequence-length s)
[ s s- ( : (~Sequence τ))]
#:fail-unless (pure? #'s-)
------------------------------
[ (sequence-length- s-) ( : Int)])

View File

@ -3,19 +3,24 @@
(provide Set
(for-syntax ~Set)
set
set-member?
set-add
set-remove
set-count
;; set-member?
;; set-add
;; set-remove
;; set-count
set-union
set-subtract
set-intersect
list->set
set->list
(typed-out [[set-first- : ( (X) (→fn (Set X) X))]
set-first]
[[set-empty?- : ( (X) (→fn (Set X) Bool))]
set-empty?]))
;; list->set
;; set->list
(typed-out [[set-first- : ( (X) (→fn (Set X) X))] set-first]
[[set-empty?- : ( (X) (→fn (Set X) Bool))] set-empty?]
[[set-count- : ( (X) (→fn (Set X) Int))] set-count]
[[set-add- : ( (X) (→fn (Set X) X (Set X)))] set-add]
[[set-remove- : ( (X) (→fn (Set X) X (Set X)))] set-remove]
[[set-member?- : ( (X) (→fn (Set X) X Bool))] set-member?]
[[list->set- : ( (X) (→fn (List X) (Set X)))] list->set]
[[set->list- : ( (X) (→fn (Set X) (List X)))] set->list]
))
(require "core-types.rkt")
(require (only-in "prim.rkt" Int Bool))
@ -35,38 +40,6 @@
---------------
[ (#%app- set- e- ...) (Set (U τ ...))])
(define-typed-syntax (set-count e)
[ e e- (~Set _)]
#:fail-unless (pure? #'e-) "expression must be pure"
----------------------
[ (#%app- set-count- e-) Int])
(define-typed-syntax (set-add st v)
[ st st- (~Set τs)]
#:fail-unless (pure? #'st-) "expression must be pure"
[ v v- τv]
#:fail-unless (pure? #'v-) "expression must be pure"
-------------------------
[ (#%app- set-add- st- v-) (Set (U τs τv))])
(define-typed-syntax (set-remove st v)
[ st st- (~Set τs)]
#:fail-unless (pure? #'st-) "expression must be pure"
[ v v- τs]
#:fail-unless (pure? #'v-) "expression must be pure"
-------------------------
[ (#%app- set-remove- st- v-) (Set τs)])
(define-typed-syntax (set-member? st v)
[ st st- (~Set τs)]
#:fail-unless (pure? #'st-) "expression must be pure"
[ v v- τv]
#:fail-unless (pure? #'v-) "expression must be pure"
#:fail-unless (<: #'τv #'τs)
"type mismatch"
-------------------------------------
[ (#%app- set-member?- st- v-) Bool])
(define-typed-syntax (set-union st0 st ...)
[ st0 st0- (~Set τ-st0)]
#:fail-unless (pure? #'st0-) "expression must be pure"
@ -91,15 +64,3 @@
#:fail-unless (all-pure? #'(st- ...)) "expressions must be pure"
-------------------------------------
[ (#%app- set-subtract- st0- st- ...) (Set τ-st0)])
(define-typed-syntax (list->set l)
[ l l- (~List τ)]
#:fail-unless (pure? #'l-) "expression must be pure"
-----------------------
[ (#%app- list->set- l-) (Set τ)])
(define-typed-syntax (set->list s)
[ s s- (~Set τ)]
#:fail-unless (pure? #'s-) "expression must be pure"
-----------------------
[ (#%app- set->list- s-) (List τ)])