> On Jul 7, 2019, at 10:24 AM, 曹朝 <[email protected]> wrote:
> 
> This is a simple algorithm for compute the shortest edit distance, it can 
> work with `#lang racket/base`.
> But in Typed Racket, I just got the error message: "insufficient type 
> information to typecheck". I don't know why this code can't pass the type 
> checker.
> Someone can help? Thank you.
> 
> #lang typed/racket/base
> (require math/array)
> 
> (: shortest-edit-distance (-> String String Integer))
> (define (shortest-edit-distance str0 str1)
> (let* ([l0 : Integer (string-length str0)]
>        [l1 : Integer (string-length str1)]
>        [table : (Mutable-Array Integer) (array->mutable-array (make-array 
> (vector l0 l1) 0))])
>   (for*/last : Integer ([i0 : Integer (in-range l0)]
>                         [i1 : Integer (in-range l1)])
>     (let* ([c0 : Char (string-ref str0 i0)]
>            [c1 : Char (string-ref str1 i1)]
>            [base : Integer (cond
>                              [(and (= i0 0) (= i1 0)) 0]
>                              [(= i0 0) (array-ref table (vector i0 (sub1 
> i1)))]
>                              [(= i1 0) (array-ref table (vector (sub1 i0) 
> i1))]
>                              [else (min (array-ref table (vector i0 (sub1 
> i1)))
>                                         (array-ref table (vector (sub1 i0) 
> i1))
>                                         (array-ref table (vector (sub1 i0) 
> (sub1 i1))))])]
>            [answer : Integer (if (char=? c0 c1) base (add1 base))])
> 
>       (array-set! table (vector i0 i1) answer)
>       answer))))

As Matthias Felleisen said, the `for*/last` form is not yet supported by Typed 
Racket. The 6 forms for/and, for/first, for/last, for*/and, for*/first, and 
for/last are documented as "Like the above, except they are not yet supported 
by the typechecker."

However, many uses of `for/first` can be replaced with `for/or`, and many uses 
of `for/last` can be replaced with `for/fold`. If you see

(for*/last : type (clause ...)
  body)

you can replace it with

(for*/fold ([_unused : type #f])
           (clause ...)
  body)

and get the same result.

There is also another problem with your code that prevents it from 
type-checking. The `for*/last` form or the `for*/fold` replacement can return 
#false, and that means you have to replace the result type `Integer` with `(U 
Integer #f)` for it to type-check. However, that's probably incorrect since an 
edit-distance should always be defined, so either you need to change how you 
iterate or handle the #false differently... I'm not sure.

Alex Knauth

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CBA4BD58-538E-42CB-8446-C2A1F1573B40%40knauth.org.
For more options, visit https://groups.google.com/d/optout.

Reply via email to