Tại sao các hàm tạo dữ liệu có cùng tên không được phép trong các hàm tạo kiểu khác nhau?


11

Khai báo sau đây có lỗi:

type Vec2d = (Float, Float)
type Vec3d = (Float, Float, Float)
-- Rect x y defines a rectangle spanning from (0,0) to (x,y)
data Obj2d = Rect Float Float
           | Translate Vec2d Obj2d
-- Cuboid x y z defines a cuboid spanning from (0,0,0) to (x,y,z)
data Obj3d = Cuboid Float Float Float
           | Translate Vec3d Obj3d

cụ thể là Multiple declarations of 'Translate'.

Bây giờ, tôi tự hỏi tại sao giới hạn này đã được giới thiệu?

Nếu không có giới hạn, người ta có thể viết

Translate (1, 1) Rect 2 2Translate (1, 2, 3) Cuboid 1 1 1, âm thanh tự nhiên.

Tôi không (ngay lập tức) xem làm thế nào điều này có thể dẫn đến việc đặt giá thầu phân tích vấn đề không cho phép sử dụng cùng tên, loại có thể được suy ra bởi đối số ( Rect 2 2là một Obj2d, Cuboid 1 1 1là một Obj3d).

Tôi chắc chắn có một lý do chính đáng để các nhà thiết kế ngôn ngữ chọn không cho phép sử dụng cùng tên cho các nhà xây dựng dữ liệu thuộc các loại khác nhau, nhưng tôi muốn tìm hiểu: tại sao, khi nó không thực sự cần thiết?

(Và định hướng loại là kinh doanh bánh mì và bơ của Haskell!)


3
Về loại đang được suy luận bởi đối số: Bạn có biết rằng đôi khi loại đối số được suy ra từ loại hàm ?

@delnan Tôi không biết điều đó ... nghe có vẻ như là một câu trả lời cho tôi. Tôi đã luôn luôn nghĩ rằng suy luận là từ dưới lên, mặc dù tôi có thể thấy độ phân giải không rõ ràng bằng cách sử dụng thông tin loại từ phía bên kia của biểu đồ loại mà bạn mô tả là một yếu tố quyết định ... hình ảnh tinh thần của tôi cho đây là loại trả về ở dưới cùng của biểu đồ và hàm gọi ở trên cùng, độ phân giải là một tổng hợp được hình thành bằng cách gấp từ dưới lên, nhưng đó không phải là toàn bộ bức tranh, bạn đang nói gì? Không có gì đáng ngạc nhiên, trong một ngôn ngữ được gõ phụ thuộc với sự suy luận hoàn hảo, điều này có lẽ chính xác hơn ..
Jimmy Hoffa

Câu trả lời:


13

Đó là bởi vì các hàm tạo dữ liệu chỉ là các hàm và quá tải hàm không được phép trong Haskell. Có thể rõ ràng hơn nếu bạn sử dụng cú pháp GADT để xác định loại của mình:

{-# LANGUAGE GADTs #-}
data Obj2d where
    Rect :: Float -> Float -> Obj2d   -- a function from floats to obj2d's
    Translate :: Vec2d -> Obj2d       -- a function from vec2d's to Obj2d's

Tôi tin rằng họ (các nhà phát triển GHC) đang nghiên cứu các giải pháp khả thi cho vấn đề này liên quan đến việc giới thiệu một cái mới type classcho tất cả các loại có chung công cụ xây dựng dữ liệu hoặc một cái gì đó tương tự. Vì vậy, hãy theo dõi, một giải pháp cho vấn đề của bạn có thể sẽ đến sớm! (Tôi hi vọng)


Tôi chắc chắn mong muốn các type classcấu trúc này bạn đang quy định. - Lý do là: Tôi không gặp vấn đề gì, tôi có thể làm Translate2Translate3d, nhưng tôi không muốn làm ô nhiễm không gian tên.
Một Sz

Tôi không phải là nhà phát triển GHC, vì vậy chỉ cần nghe nói. Tôi hy vọng nó cũng xảy ra.
bstamour
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.