What's wrong with my code?

92 views
Skip to first unread message

曹朝

unread,
Jul 7, 2019, 12:24:02 PM7/7/19
to Racket Users
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))))

截屏2019-07-0800.15.13.png


Matthias Felleisen

unread,
Jul 7, 2019, 3:50:18 PM7/7/19
to 曹朝, Racket Users

With some for/loops in TR you’re out of luck. The expansion are too complex to type-check easily. 


<截屏2019-07-0800.15.13.png>



--
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...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/1fa2f544-9f60-4e00-a451-b42b1e4f5b0f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
<截屏2019-07-0800.15.13.png>

曹朝

unread,
Jul 8, 2019, 10:42:24 AM7/8/19
to Racket Users
Alright, thank you very much.

在 2019年7月8日星期一 UTC+8上午3:50:18,Matthias Felleisen写道:
To unsubscribe from this group and stop receiving emails from it, send an email to racket...@googlegroups.com.

Alex Knauth

unread,
Jul 9, 2019, 10:04:59 AM7/9/19
to 曹朝, Racket Users
On Jul 7, 2019, at 10:24 AM, 曹朝 <cz1...@gmail.com> wrote:


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

曹朝

unread,
Jul 9, 2019, 10:19:46 AM7/9/19
to Racket Users
🤩 Wow! I get it, thanks.

在 2019年7月9日星期二 UTC+8下午10:04:59,Alex Knauth写道:
Reply all
Reply to author
Forward
0 new messages