Tôi muốn triển khai Type Class
với một vài phương pháp mặc định, nhưng tôi gặp lỗi, rằng tôi không thể sử dụng record selectors
bên trong các định nghĩa type classes
.Bộ chọn bản ghi trong các Loại Lớp của Haskell
Mã sau về cơ bản tạo type class
xác định hàm add
, sẽ thêm phần tử vào bản ghi repr
của một số data type
. Đây là mã:
import qualified Data.Graph.Inductive as DG
class Graph gr a b where
empty :: DG.Gr a b
empty = DG.empty
repr :: gr -> DG.Gr a b
-- following function declaration does NOT work:
add :: a -> gr -> gr
add el g = g{repr = DG.insNode el $ repr g}
Trình biên dịch ném lỗi:
repr is not a record selector
In the expression: g {repr = DG.insNode el $ repr g}
In an equation for add:
add el g = g {repr = DG.insNode el $ repr g}
Có thể khai báo các phương pháp như vậy trong Haskell?
Làm rõ
Tôi cần thiết kế như vậy bởi vì tôi đã có một số data types
, mà cư xử theo cách simmilar. Giả sử, chúng tôi có A
, B
và C
data types
. Mỗi người trong số họ phải có hồ sơ repr :: DG.Gr a b
, trong đó a
và b
riêng biệt cho mỗi A
, B
và C
.
A
, B
và C
chia sẻ các chức năng tương tự, như add
hoặc delete
(mà về cơ bản thêm hoặc xóa các yếu tố để ghi repr
). Nếu các kiểu dữ liệu này chia sẻ rất nhiều hàm, hãy thực hiện các hàm trong type class
và thực hiện các trường hợp này type class
- các chức năng này sẽ được triển khai cho mỗi data type
tự động của chúng tôi.
Bổ sung Tôi rất thích một số trong số này data types
(cho phép nói rằng tôi muốn B
) để hoạt động nhẹ khác nhau khi gọi chức năng add
trên đó. Thật dễ dàng để thực hiện hành vi này khi thực hiện instance
của type class
cho B
.
Câu trả lời là "không", nhưng "loại, sử dụng ống kính", nhưng quan trọng hơn là tôi cảm thấy có một sự hiểu lầm cơ bản về những lớp học ở đâu đó ở đây. Nó sẽ giúp ích rất nhiều nếu bạn nói _why_ bạn muốn có một lớp học như vậy; chúng tôi có thể đề xuất một giải pháp thay thế thành ngữ hơn. –
@DanielWagner - Tôi đã thêm một giải thích cho vấn đề tôi đang cố gắng giải quyết - Tôi hy vọng nó là đủ rõ ràng bây giờ, tại sao tôi đang cố gắng để làm điều này :) –
Xem câu trả lời cập nhật của tôi. Trong ví dụ thứ hai, tôi sử dụng phương thức 'update' để thực hiện cập nhật thực tế (có thể được thực hiện bằng cách sử dụng cú pháp cập nhật bản ghi đó trong các cá thể), và ví dụ thứ ba sử dụng' Control.Lens'. – JJJ