<span id="mailbox-conversation"><div>would something like this work?</div>
<div><br></div>
<div>
<div>#lang typed/racket</div>
<div><br></div>
<div>(struct (U) number+unit ([amount : Real] [unit : U]))</div>
<div><br></div>
<div>(define-type Weight-Unit (U 'kg 'g 'mg 'μg))</div>
<div>(define-type Weight (number+unit Weight-Unit))</div>
<div>(define-predicate weight? Weight)</div>
<div><br></div>
<div>(: make-weight : Real Weight-Unit -> Weight)</div>
<div>(define (make-weight n u)</div>
<div>  (number+unit n u))</div>
<div><br></div>
<div id="mb-reply">(: +/weight : Weight Weight -> Weight)</div>
<div id="mb-reply">;; something something needs unit conversion</div>
<div>(define (+/weight w1 w2)</div>
<div>  (number+unit (+ (number+unit-amount w1)</div>
<div>                  (number+unit-amount w1))</div>
<div>               (number+unit-unit w1)))</div>
<div><br></div>
<div>(+/weight (make-weight 1 'kg) (make-weight 1 'kg))</div>
</div></span><div class="mailbox_signature"><br></div>
<br><br><div class="gmail_quote"><p>On Sun, Sep 28, 2014 at 11:03 AM, Alexander D. Knauth <span dir="ltr"><<a href="mailto:alexander@knauth.org" target="_blank">alexander@knauth.org</a>></span> wrote:<br></p><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><p>Because the struct is representing a unit (kilograms, meters, seconds, etc.), and a unit has a dimension (mass, length, time, etc.) and I want the type-checker to be able to know what the dimension of a unit is so that the types of functions can specify the dimension that something should have.  
<br>The real solution to this would probably be bounded polymorphism, but I was wondering if there was some other way to do it with occurrence typing in the guard or something like that.  
<br><br>On Sep 28, 2014, at 11:48 AM, Sam Tobin-Hochstadt <samth@cs.indiana.edu> wrote:
<br><br>> Why not do this with the type, instead of making this polymorphic?
<br>> 
<br>> Sam
<br>> 
<br>> On Fri, Sep 26, 2014 at 7:35 PM, Alexander D. Knauth
<br>> <alexander@knauth.org> wrote:
<br>>> Is it possible to have a struct that does certain things according to the
<br>>> guard?
<br>>> #lang typed/racket
<br>>> 
<br>>> (struct (a) foo ([a : a]) #:transparent
<br>>>  #:guard (lambda (a _)
<br>>>            (unless (exact-integer? a)
<br>>>              (error 'foo "expected Integer, given ~v" a))
<br>>>            a))
<br>>> 
<br>>> (ann (foo (ann 1 Any)) (foo Integer))
<br>>> 
<br>>> (: x : (foo Any))
<br>>> (define x (foo 1))
<br>>> 
<br>>> (ann (foo-a x) Integer)
<br>>> 
<br>>> ;. Type Checker: Polymorphic function `foo1' could not be applied to
<br>>> arguments:
<br>>> ;Argument 1:
<br>>> ;  Expected: a
<br>>> ;  Given:    Any
<br>>> ;
<br>>> ;Result type:     (foo a)
<br>>> ;Expected result: (foo Integer)
<br>>> ; in: (foo (ann 1 Any))
<br>>> ;. Type Checker: Polymorphic function `foo-a' could not be applied to
<br>>> arguments:
<br>>> ;Argument 1:
<br>>> ;  Expected: (foo a)
<br>>> ;  Given:    (foo Any)
<br>>> ;
<br>>> ;Result type:     (a : ....)
<br>>> ;Expected result: Integer
<br>>> ; in: (foo-a x)
<br>>> 
<br>>> On Sep 25, 2014, at 9:42 PM, Alexander D. Knauth <alexander@knauth.org>
<br>>> wrote:
<br>>> 
<br>>> What I’m trying to accomplish is something more like this:
<br>>> #lang typed/racket
<br>>> 
<br>>> (require "dimensions.rkt")
<br>>> 
<br>>> (struct (d) unit ([name : Any] [scalar : Positive-Real] [dimension : d])
<br>>> #:transparent
<br>>>  #:guard (lambda (name scalar dimension _)
<br>>>            (unless (dimension? dimension)
<br>>>              (error 'unit "expected Dimension, given ~v" dimension))
<br>>>            (values name scalar dimension)))
<br>>> 
<br>>> (define-type (Unitof d) (unit d))
<br>>> 
<br>>> (define-type Unit (Unitof Dimension))
<br>>> 
<br>>> (define Unit? (make-predicate Unit))
<br>>> 
<br>>> (define-type Unitish
<br>>>  (U (Unitof Any)
<br>>>     Dimension
<br>>>     Positive-Real))
<br>>> 
<br>>> (: ->unit : (All (d) (case-> [(Unitof d) -> (Unitof d)]
<br>>>                             [Unitish -> Unit])))
<br>>> (define (->unit u)
<br>>>  (cond [(unit? u)
<br>>>         (unless (Unit? u) ; this should never happen anyway because of the
<br>>> guard
<br>>>           (error '->unit "expected (Unitof Dimension), given ~v" u))
<br>>>         u]
<br>>>        [(dimension? u) (unit u 1 u)]
<br>>>        [(positive-real? u) (unit u u dimensionless-dimension)]))
<br>>> 
<br>>> 
<br>>> On Sep 25, 2014, at 6:19 PM, Sam Tobin-Hochstadt <samth@cs.indiana.edu>
<br>>> wrote:
<br>>> 
<br>>> No, I don't think you can do this. Can you say more about what you're
<br>>> trying to accomplish?
<br>>> 
<br>>> Sam
<br>>> 
<br>>> On Thu, Sep 25, 2014 at 6:15 PM, Alexander D. Knauth
<br>>> <alexander@knauth.org> wrote:
<br>>> 
<br>>> Do any of you have any advice for getting a function like this to
<br>>> type-check?
<br>>> #lang typed/racket
<br>>> 
<br>>> (: check-int : (All (a) (case-> [a -> a]
<br>>>                               [Any -> Integer])))
<br>>> (define (check-int int)
<br>>> (unless (exact-integer? int)
<br>>>   (error 'check-int "expected Integer, given ~v" int))
<br>>> int)
<br>>> 
<br>>> ;. Type Checker: type mismatch
<br>>> ;  expected: a
<br>>> ;  given: Integer in: int
<br>>> 
<br>>> 
<br>>> 
<br>>> ____________________
<br>>> Racket Users list:
<br>>> http://lists.racket-lang.org/users
<br>>> 
<br>>> 
<br>>> ____________________
<br>>> Racket Users list:
<br>>> http://lists.racket-lang.org/users
<br>>> 
<br>>> 
<br><br><br>____________________
<br>  Racket Users list:
<br>  http://lists.racket-lang.org/users
<br></p></blockquote></div><br>