KRC
KRC

Reputation: 328

require/typed contract in racket fails

I've tried looking at the docs but i can't find an example that i can use for my case. I need to import break from srfi/1.

Here's my attempt. The example works in #lang racket.

#lang typed/racket

(require/typed (only-in srfi/1 break)
               ;[break (All (T) (-> (-> T Boolean) (Listof T) (Listof T)))])
               ;[break (All (T) (-> (-> T Boolean) (Values (Listof T) (Listof T))))])
               [break (All (T) (-> (-> String (U False (Listof T))) (Listof T) (Listof T)))])

(define entity-types '("3DFACE"  "3DSOLID"  "ACAD_PROXY_ENTITY" "ARC" "ARCALIGNEDTEXT"  "ATTDEF"  "ATTRIB"  "BODY"  "CIRCLE" "DIMENSION" "ELLIPSE"  "HATCH" "IMAGE"  "INSERT"  "LEADER"  "LINE" "LWPOLYLINE" "MLINE"  "MTEXT"  "OLEFRAME"  "OLE2FRAME"  "POINT" "POLYLINE" "RAY"  "REGION"  "RTEXT"  "SEQEND"  "SHAPE"  "SOLID" "SPLINE" "TEXT"  "TOLERANCE"  "TRACE"  "VERTEX"  "VIEWPORT" "WIPEOUT" "XLINE"))
(define lst '("ENTITIES" "0" "LINE" "5" "BA1C" "330" "1F" "100" "AcDbEntity" "8" "0" "370" "0" "100" "AcDbLine" "10" "253.2926653556182" "20" "1478.621431186484" "30" "0.0" "11" "253.2876653556182" "21" "1478.621431186484" "31" "0.0" "0" "LINE" "5" "BA1D" "330" "1F" "100" "AcDbEntity" "8" "0" "370" "0" "100" "AcDbLine" "10" "253.2876653556182" "20" "1478.621431186484" "30" "0.0" "11" "253.2876653556182" "21" "1476.655431186484" "31" "0.0" "0" "LINE" "5" "BA1E" "330" "1F" "100" "AcDbEntity" "8" "0" "370" "0" "100" "AcDbLine" "10" "253.2926653556182" "20" "1476.655431186484" "30" "0.0" "11" "253.2876653556182" "21" "1476.655431186484" "31" "0.0" "0" "LINE" "5" "BA1F" "330" "1F" "100" "AcDbEntity" "8" "0" "370" "0" "100" "AcDbLine" "10" "253.2926653556182" "20" "1476.655431186484" "30" "0.0" "11"))

(break (lambda ([x : String]) (member x entity-types)) lst)

Upvotes: 3

Views: 106

Answers (2)

Alexis King
Alexis King

Reputation: 43892

This is the type I would assign to break:

(require/typed
 (only-in srfi/1 break)
 [break (All [T] (-> (T -> Any) (Listof T) 
                     (Values (Listof T) (Listof T))))])

The predicate function can return anything. If it returns #f, it will be treated as falsy, and any other result will be treated as truthy. Furthermore, as soegaard mentioned, the Values type constructor is needed to indicate that break returns multiple values.

However, Racket actually includes a function very similar to break, but it's actually equivalent to span. The function itself is called splitf-at, and it's very easy to implement break in terms of that function rather than using srfi/1.

(: break (All [T] (-> (T -> Any) (Listof T) 
                      (Values (Listof T) (Listof T)))))
(define (break pred lst)
  (splitf-at lst (negate pred)))

Upvotes: 2

soegaard
soegaard

Reputation: 31145

This works for me:

(require/typed (only-in srfi/1 break)
               [break (All (T) (-> (-> T (U False (Listof T))) (Listof T) 
                                   (values (Listof T) (Listof T))))])

Note that member returns either #f or a list whose first element is the element searched for. Therefore the predicate in the example (lambda ([x : String]) (member x entity-types)) has the type (-> T (U False (Listof T))).

Finally values is needed to indicate that break returns multiple values.

Upvotes: 3

Related Questions