如何在键入的球拍中解决此类型不匹配问题?

时间:2016-03-12 13:02:45

标签: racket typed-racket

我尝试在类型的球拍中重写以下SML代码,但是出现类型不匹配错误,我对此感到困惑。

datatype 'a pizza = Bottom
                      | Topping of ('a * ('a pizza))

datatype fish = Anchovy
              | Lox
              | Tuna

fun eq_fish (Anchovy,Anchovy)
      = true
      | eq_fish (Lox,Lox)
        = true
      | eq_fish (Tuna,Tuna)
        = true
      | eq_fish (a_fish,another_fish)
    = false

fun rem_fish (x,Bottom)
  = Bottom
  | rem_fish (x,Topping(t,p))
    = if eq_fish(t,x)
      then rem_fish(x,p)
      else Topping(t,(rem_fish(x,p)))

这里输入的球拍代码:

(define-type (pizza a)
  (U Bottom
     (Topping a)))

(struct Bottom ())
(struct (a) Topping ([v : a] [w : (pizza a)]))

(define-type fish
  (U Anchovy
     Lox
     Tuna))

(struct Anchovy ())
(struct Lox ())
(struct Tuna ())

(: eq-fish (-> fish fish Boolean))
(define (eq-fish f1 f2)
  (match f1
    [(Anchovy)
     (Anchovy? f2)]
    [(Lox)
     (Lox? f2)]
    [(Tuna)
     (Tuna? f2)]
    [_ false]))

(: rem-fish (∀ (a) (fish (pizza a) -> (pizza a))))
(define (rem-fish x pizza)
  (match pizza
    [(Bottom) (Bottom)]
    [(Topping t p)
     (if (eq-fish t x)
         (rem-fish x p)
         (Topping t (rem-fish x p)))]))

类型检查器:类型不匹配 ;预期:鱼 ;给出:a ; in:t

1 个答案:

答案 0 :(得分:2)

这是因为你隐含地期望afish,但是类型检查器会查看你给它的类型,所以它不知道。在ML中,如果我理解正确,则会推断rem-fish的类型应为fish (pizza fish) -> (pizza fish),而不是fish (pizza a) -> (pizza a)。如果您将功能更改为使用该类型,则代码可以正常工作:

(: rem-fish : fish (pizza fish) -> (pizza fish))
(define (rem-fish x pizza)
  (match pizza
    [(Bottom) (Bottom)]
    [(Topping t p)
     (if (eq-fish t x)
         (rem-fish x p)
         (Topping t (rem-fish x p)))]))

它必须是fish而不是a的原因是,当您在eq-fish上使用t时,t来自(pizza a) 1}}所以它有a类型。但这不起作用,因为eq-fish期望fish