3
votes

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)
2

2 Answers

3
votes

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.

2
votes

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)))