Gõ cho các cách thức giá trị có thể khác nhau


8

Tôi đang tìm kiếm một khái niệm trong lý thuyết loại mà tôi chắc chắn có thể đã được khám phá, nhưng không biết tên đằng sau.

Chúng ta hãy xem xét một ngôn ngữ giống như ML với các loại sản phẩm và tổng và hệ thống loại giống như Hindley-Milner. Tôi sẽ sử dụng cú pháp OCaml.

Tôi đang tự hỏi về cách hai giá trị khác nhau có thể khác nhau.

Sử dụng

Trường hợp sử dụng của tôi là viết các thông báo lỗi "rõ ràng hơn" trong thư viện giống như xUnit: nếu hai giá trị khác nhau khi chúng được dự kiến ​​là bằng nhau, điều này có thể giúp xây dựng một thông báo rõ ràng hơn:

Trước:

Giá trị khác nhau: dự kiến {x = [1;2;3;4], y = "a long string"}, có{x = [1;2;3;3], y = "a long string"}

Sau:

Giá trị khác nhau: tại vị trí .x[3], dự kiến ​​4, có 3.

(có thể có mối quan hệ với các ống kính chức năng vì cuối cùng chúng ta sẽ xây dựng một ống kính thành một giá trị nhỏ hơn khác nhau).

Các loại sản phẩm

Ví dụ:

type p =
  { x : int
  ; y : string
  }

Bình đẳng có thể được định nghĩa là:

let equal a b =
  equal_int a.x b.x && equal_string a.y b.y

Nhưng nó cũng có thể xác định sự khác biệt:

type delta_p =
  | Equal
  | Diff_x of int * int
  | Diff_y of string * string

let diff_p a b =
  if not (equal_int a.x b.x) then
    Diff_x (a.x, b.x)
  else if not (equal_string a.y b.y) then
    Diff_y (a.y, b.y)
  else
    Equal

(có thể có ý nghĩa khi định nghĩa một delta_intloại như int * intthể hiện rằng nó là đệ quy)

Các loại tổng

Đối với loại tổng có nhiều cách khác nhau: có một hàm tạo khác nhau hoặc một giá trị khác

type s = X of int | Y of string

type ctor_s =
  | Ctor_X
  | Ctor_Y

type delta_s =
  | Equal
  | Diff_ctor of ctor_s * ctor_s
  | Diff_X of int * int
  | Diff_Y of string * string

let diff_s a b = match (a, b) with
  | X xa, X xb ->
    if equal_int xa xb then
      Equal
    else
      Diff_X (xa, xb)
  | (* Y case similar *)
  | X _, Y _ -> Diff_ctor (Ctor_X, Ctor_Y)
  | Y _, X _ -> Diff_ctor (Ctor_Y, Ctor_X)

Tên của khái niệm này là gì? Tôi có thể tìm hiểu thêm về điều này ở đâu?

Cảm ơn!


2
Một dây kéo là một "con trỏ" đến một vị trí. Tôi không biết nếu có ai nghiên cứu cách hiển thị khóa kéo độc đáo cho người dùng.
Andrej Bauer

Nó không thực sự được thảo luận chung chung, nhưng trường hợp sử dụng làm tôi nhớ đến The View from the Left , phần 7, nơi họ thực hiện một trình kiểm tra loại được xác minh báo cáo sự khác biệt chính xác giữa loại dự kiến ​​và loại chung. Hình 15 có kiểu Isnt tương tự với trường hợp sử dụng của bạn.
Tối đa mới

Cảm ơn các con trỏ. Dường như với tôi, dây kéo liên quan nhiều đến việc "di chuyển" sang trái và phải hơn là tập trung, nhưng đó cũng là một hiệu ứng mà họ có. Điều đó có vẻ khá liên quan đến các mẫu xem thực sự.
Étienne Millon

Câu trả lời:


9

Tôi nghĩ rằng bạn đang tìm kiếm một biến thể đánh máy chống thống nhất . Chống thống nhất có thể được mô tả như sau. Thứ nhất, giả sử rằng chúng ta có một ngữ pháp của các điều khoản như sau:

t ::= () | (t, t) | C t | X 

Ở đây, ()(t, t)biểu thị các đơn vị và cặp, C tlà một thuật ngữ với hàm tạo hàng đầu và Xlà một biến thuật ngữ, có thể được thay thế cho bất kỳ thuật ngữ nào.

Vấn đề chống thống nhất nói rằng, nếu bạn đưa ra hai điều khoản t1t2, thuật ngữ chung ít nhất tsao cho có sự thay thế s1s2như vậy s1(t) = t1s2(t) = t2.

Như một ví dụ cụ thể, đưa ra hai điều khoản

t1 = Cons(3, Cons(2, Cons(1, Nil)))
t2 = Cons(1, Cons(2, Cons(3, Nil)))

thuật toán chống thống nhất sẽ trả về trình chống khử

t = Cons(X, Cons(2, Cons(Y, Nil)))

bởi vì sự thay thế s1 = [X:3, Y:1]s2 = [X:1, Y:3]áp dụng tsẽ cung cấp cho bạn t1t2trở lại. Bên cạnh đó, chúng tôi cần chỉ định "ít chung nhất" vì nếu không:

t' = Z 

với sự thay thế s1 = [Z:t1]s2 = [Z:t2]sẽ làm các thủ thuật.

Chống thống nhất được phát minh bởi Gordon Plotkin, và là một thuật toán đơn giản thú vị. Giả sử bạn có chức năng tạo tên tiêm . Sau đó, chúng ta có thể tìm thấy một chất chống kích thích như saugen :Term×TermVmộtr

antiunify ()       ()         = ()
antiunify (t1, t2) (t1', t2') = (antiunify t1 t1', antiunify t2 t2')
antiunify (C t)    (C t')     = C (antiunify t t')
antiunify t        t'         = gen(t, t') -- default: t and t' dissimilar 

Tăng cường thuật toán này để trả về hai sự thay thế s1s2tôi rời đi như một bài tập.


Cảm ơn về thuật ngữ (ý định chơi chữ). Có vẻ như nó có thể là nó. Một đại số đánh máy của "con đường" như thế này sẽ là tuyệt vời. Cảm ơn!
Étienne Millon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.