Hi everyone,

Recently I've been experimenting with Typed Racket and trying to gradually type 
my code base.
One of the functions that I need to write is to extract a list of strings from 
a JSON object, if it has following form:

    {
      "Type": "DTHidden",
      "Data": { "Type": "CDUsers",
                "Data": ["datum1", "datum2"] }
    }

The way I used to structure it in Racket is to have a function `is-cdusers?` 
with the contract `jsexpr? -> boolean?`, which would check that the JSON object 
has the right shape; and a separate function `get-cdusers-data` with the 
contract `is-cdusers? -> listof string?`.

However, after playing a bit with Typed Racket I decided that it was necessary, 
according to my understanding of occurrence typing, to have a single function 
`get-cdusers-data` with the type `JSExpr -> (U False (Listof String))`.
In order to get it to work I ended up writing a long chain of conditionals:


    (: get-cdusers-data (-> JSExpr (U False (Listof Any))))
    (define (get-cdusers-data js)
      (if (and (hash? js)
               (equal? DTHidden (hash-ref js 'Type #f)))
          (let ([js (hash-ref-def js 'Data [ann #hasheq() JSExpr])])
            (if (and (hash? js)
                     (equal? CdUsers (hash-ref js 'Type #f)))
                (let ([data (hash-ref js 'Data)])
                  (if (hash? data)
                      (let ([x (hash-ref js 'Data #f)])
                        (and (list? x) x))
                      #f))
                #f))
          #f))

Needless to say, this is a bit impractical and error-prone to write.
Does anyone know if there is a better approach to this?

>From my experience with typed languages I would get that the most principle 
>approach is to have an algebraic data type that represents all the underlying 
>data structures, something like

    type reply = ... | CDUsers of string list | ...

and then have a single function to converts a JSExpr into that data type.

I was hoping to avoid that, because I do enjoy working with the JSExpr type 
directly in Racket.

Does anyone have advice/experience with problems like this?

Best wishes,
-Ed

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/bc4f73636c65f68b7dae4959ea18dc19%40disroot.org.

Reply via email to