简体   繁体   中英

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)

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM