Open NoahStoryM opened 2 years ago
I'm confused about the motivation here. The code you started with seems like how I would write the program in Racket, and thus how I'd want to write the program in Typed Racket as well.
If the problem is that we can't easily define combinators over predicates to put in a library, then that seems like a separate issue from adding things to typed/racket
itself, which is intended to be a typed version of the contents of racket
.
However, it seems like these definitions of and/p
and or/p
work correctly, as well as your definition of not/p
:
(: and/p (All (A B) [-> (pred A) (pred B) (pred (∩ A B))]))
(define and/p (λ (p q) (λ (a) (and (p a) (q a)))))
(: or/p (All (A B) [-> (pred A) (pred B) (pred (U A B))]))
(define or/p (λ (p q) (λ (a) (or (p a) (q a)))))
One further problem is that not/p
doesn't produce a predicate in the sense your and/p
expects. That's because Typed Racket doesn't have negation types. If you don't use not/p
but instead write (lambda (x) (equal? 0 x))
then it works.
My initial motivation was that I found myself often use predicate
to check the same variable in cond
by and
, or
and not
, it looks cumbersome in these cases.
And in most cases, flat contract
and predicate
are very similar. In fact, my original idea was to add types to and/c
, or/c
and not/c
(maybe unsafe should be used here):
(require/typed racket/contract/base
[or/c (All (A ...) [-> (pred A) ... A (pred (U A ... A))])]
[and/c (All (A ...) [-> (pred A) ... A (pred (∩ A ... A))])]
[not/c (All (A) [-> (pred A) [-> Any Boolean: #:+ (! A) #:- A]])])
But now it seems that because TR does not have negation types, and there is no way to use ooo
in U
and ∩
, so there is no way to achieve them?
Maybe as you said, I should add (All (A B C D E) (case-> ...))
to and/c
and or/c
here. But I think the problem here is that if ooo
cannot be used in some return value types, it will affect the definition of some composite functions.
I'm still a bit confused. It sounds like you want to program in a more point-free style when writing predicates. Contract combinators can be used for this, but (a) not/c
doesn't work that well because TR lacks negation and (b) it's not possible to use ...
with union and intersection so you would have to limit things to a fixed arity.
That all seems accurate, but then I don't understand what the feature request would be.
I'm sorry my thoughts were a bit confusing, maybe I need some time to sort out them. I wonder if you are willing to provide types for and/c
and or/c
in TR? Maybe in this way:
(provide or/c and/c)
(require typed/racket/unsafe)
(unsafe-require/typed racket/contract/base
[or/c (All (A B C D E)
(case-> [-> (pred Any)]
[-> (pred A) (pred A)]
[-> (pred A) (pred B) (pred (U A B))]
[-> (pred A) (pred B) (pred C) (pred (U A B C))]
[-> (pred A) (pred B) (pred C) (pred D) (pred (U A B C D))]
[-> (pred A) (pred B) (pred C) (pred D) (pred E) (pred (U A B C D E))]))]
[and/c (All (A B C D E)
(case-> [-> (pred Nothing)]
[-> (pred A) (pred A)]
[-> (pred A) (pred B) (pred (∩ A B))]
[-> (pred A) (pred B) (pred C) (pred (∩ A B C))]
[-> (pred A) (pred B) (pred C) (pred D) (pred (∩ A B C D))]
[-> (pred A) (pred B) (pred C) (pred D) (pred E) (pred (∩ A B C D E))]))])
Is your feature request related to a problem? Please describe. Example Code
Describe the solution you'd like I hope we can use
and/p
,or/p
, andnot/p
so that we can definep
in this way:Describe alternatives you've considered This is the definition I tried: (I'm not sure whether using
for
in the definition of predicate will cause problems, but I think it should be allowed)[Optional] Additional context Some additional suggestions
∩
, will it be better to also support∪
?and/p
,or/p
, andnot/p
,any?
andnothing?
are somewhat similar totrue
andfalse
. Should we addany?
andnothing?
in TR? (I feel that in some cases where predicate is used as a function parameter,any?
andnothing?
may play a role similar toBoolean
)