Getters và Setters trong ngôn ngữ chức năng


9

Một trong những nguyên lý của Lập trình hàm là việc sử dụng Hàm thuần túy. Hàm Pure là một hàm không có tác dụng phụ và trong suốt về mặt tham chiếu.

Getters không trong suốt về mặt tham chiếu - nếu Setter được gọi giữa các lệnh gọi đến Getter, giá trị trả về của Getter thay đổi ngay cả khi các tham số của nó không (thường không có tham số)

Setters tạo ra các hiệu ứng phụ - Gọi một Setter thường thao túng một giá trị không phải là giá trị trả về của nó (trên thực tế, theo truyền thống, một setter không trả về gì cả)

Tôi biết trong Scala, chúng ta chỉ chấp nhận thực tế là chúng ta đang kết hợp hai mô hình (hướng theo chức năng và đối tượng) và sử dụng getters / setters như trong ngôn ngữ như Java.

Trong một ngôn ngữ như Haskell (mà tôi không thông thạo, nhưng tôi được bảo là có ngôn ngữ chức năng "thuần túy") Tôi chỉ tò mò, làm thế nào bạn mô hình hóa các thuộc tính trên các đối tượng sao cho Getters trong suốt và Setters Có tác dụng phụ miễn phí?

Giải pháp sẽ là trả lại một bản sao của đối tượng mà setter được gọi là giá trị trả về của setter và bản sao này có chứa thay đổi đối với giá trị thuộc tính không?


8
Getters và setters có đối tượng là tham số - mặc dù nó thường ẩn - vì vậy getters trong suốt tham chiếu.

@delnan, chỉ khi thuộc tính mà nó đang đọc là bất biến.
dan_waterworth

3
@dan_waterworth: Chỉ khi chúng ta đọc "cùng" trong "minh bạch tham chiếu" là danh tính đối tượng. Nếu thực tế thuộc tính cơ bản là khác nhau thì nó là một cuộc gọi với các đối số khác nhau (phù hợp với hầu hết các định nghĩa về đẳng thức). Điều này là bỏ qua một luồng khác gọi một setter và hoàn thành nó giữa cuộc gọi đến getter và getter kết thúc, nhưng trong trường hợp đó bạn vẫn gặp vấn đề nghiêm trọng hơn.

Câu trả lời:


7

Chính xác. Xem phương pháp lớp trường hợp copy, hoặc khái niệm chung về ống kính.

Đặc biệt, nếu nhà nước cần thay đổi, bạn sẽ sử dụng một đơn nguyên Bang. Thay đổi đối với trạng thái đơn nguyên đó có thể được thực hiện thông qua các ống kính, giúp trích xuất thông tin từ "trạng thái" và thay đổi dễ dàng.

Xem thêm câu hỏi này về vấn đề chung xuất phát từ một cấu trúc sâu như "trạng thái" và thay đổi nó. Các câu trả lời có liên kết tốt trên cả ống kính và khóa kéo nếu bạn muốn tìm hiểu sâu hơn về điều đó.


Câu hỏi Daniel: có bất kỳ lý do cụ thể nào mà copy () được gắn với các lớp Case không? Điều này dường như không cụ thể đối với các nhu cầu (từ sai, nhưng không thể nghĩ ra một loại khác) của các lớp Case, dường như (đối với tôi) có nhiều tính năng phù hợp với tất cả các lớp. Điều gì xảy ra nếu tôi cần copy () trên lớp không phải trường hợp của tôi? Có một đặc điểm tôi có thể sử dụng để có được chức năng đó?
ThaDon

1
Các lớp trường hợp @ThaDon được cho là được xác định bởi các tham số hàm tạo của chúng - đẳng thức, mã băm và trình trích xuất của chúng dựa trên giả định này và phương thức sao chép cũng vậy. Trên các lớp không phải là trường hợp, mọi người đều đoán xem các tham số của hàm tạo có phải là tất cả những gì cần thiết để sao chép một lớp hay không. Tuy nhiên, bạn có thể dễ dàng viết phương pháp sao chép của riêng bạn.
Daniel C. Sobral

11

Chà, trong Haskell, các đối tượng (thường) là bất biến, do đó, getters (mà bạn nhận được khi bạn sử dụng cú pháp bản ghi) hoặc các hàm hoạt động như getters được minh bạch tham chiếu. Và sau đó, bạn không "đặt" các giá trị trên các đối tượng - nếu bất cứ điều gì bạn tạo một đối tượng mới tương tự như đối tượng cũ, nhưng với một giá trị khác cho một trong các trường. Đây cũng là một chức năng thuần túy.


1
"Đối tượng là (thường) bất biến" khi nào thì không?
sara

-1

"Getters và setters có đối tượng là tham số - mặc dù nó thường ẩn - vì vậy getters là trong suốt tham chiếu. - delnan"

Minh bạch tham chiếu có nghĩa là hàm LUÔN LUÔN trả về cùng một đầu ra cho cùng một đầu vào; vì vậy nếu một thuộc tính đối tượng đã được thay đổi bởi một setter, bạn sẽ không trả lại cùng một đầu ra. :)


Nhưng, nếu đối tượng được thay đổi bởi một setter, đầu vào của getter (tức là đối số tự ẩn) ĐÃ thay đổi.
Stephen C. Steel

1
Giá trị / con trỏ tham chiếu đối tượng không thay đổi trừ khi đối tượng đã được di chuyển trên heap.
Casey Hawthorne

5
Có, nhưng về mặt logic, đầu vào ẩn là chính đối tượng, không phải giá trị của con trỏ.
Stephen C. Steel

"Nếu một thuộc tính đối tượng đã được thay đổi bởi một setter, bạn sẽ không trả lại cùng một đầu ra": Về mặt chức năng, bạn đã phá hủy đối tượng đầu tiên và tạo một đối tượng mới. Vì lý do hiệu suất (tránh sao chép và cập nhật các tham chiếu từ đối tượng cũ sang đối tượng mới), bạn đang lưu trữ đối tượng mới trong cùng vùng nhớ có chứa đối tượng cũ.
Giorgio
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.