Có nên xây dựng các đối tượng trạng thái được mô hình hóa với một loại hiệu ứng?
Nếu bạn đã sử dụng một hệ thống hiệu ứng, rất có thể nó có một Ref
loại để đóng gói một cách an toàn trạng thái có thể thay đổi.
Vì vậy, tôi nói: mô hình đối tượng nhà nước vớiRef
. Vì việc tạo (cũng như quyền truy cập) đã là một hiệu ứng, điều này sẽ tự động làm cho việc tạo dịch vụ trở nên hiệu quả.
Điều này gọn gàng bên bước câu hỏi ban đầu của bạn.
Nếu bạn muốn tự quản lý trạng thái có thể thay đổi nội bộ một cách thường xuyên, var
bạn phải tự đảm bảo rằng tất cả các thao tác chạm vào trạng thái này đều được coi là hiệu ứng (và rất có thể cũng được thực hiện an toàn theo luồng), rất tẻ nhạt và dễ bị lỗi. Điều này có thể được thực hiện và tôi đồng ý với câu trả lời của @ atl rằng bạn không nhất thiết phải tạo ra đối tượng có trạng thái hiệu quả (miễn là bạn có thể sống với sự mất tính toàn vẹn tham chiếu), nhưng tại sao không tự cứu mình khỏi rắc rối và nắm lấy Các công cụ của hệ thống hiệu ứng của bạn tất cả các cách?
Tôi đoán tất cả những điều này là tinh khiết và xác định. Chỉ không tham chiếu minh bạch vì trường hợp kết quả là khác nhau mỗi lần. Đó có phải là thời điểm tốt để sử dụng một loại hiệu ứng?
Nếu câu hỏi của bạn có thể được đăng lại như
Các lợi ích bổ sung (trên cùng của việc triển khai hoạt động chính xác bằng cách sử dụng "kiểu chữ yếu hơn") về tính minh bạch tham chiếu và lý luận cục bộ đủ để biện minh cho việc sử dụng loại hiệu ứng (đã được sử dụng cho truy cập và đột biến trạng thái) cũng cho trạng thái sự sáng tạo ?
sau đó: Vâng, hoàn toàn .
Để đưa ra một ví dụ về lý do tại sao điều này hữu ích:
Những điều sau đây hoạt động tốt, mặc dù việc tạo dịch vụ không tạo ra hiệu quả:
val service = makeService(name)
for {
_ <- service.doX()
_ <- service.doY()
} yield Ack.Done
Nhưng nếu bạn cấu trúc lại lỗi này như dưới đây, bạn sẽ không gặp lỗi thời gian biên dịch, nhưng bạn sẽ thay đổi hành vi và rất có thể đã đưa ra lỗi. Nếu bạn đã khai báo hiệu makeService
quả, việc tái cấu trúc sẽ không kiểm tra kiểu và bị trình biên dịch từ chối.
for {
_ <- makeService(name).doX()
_ <- makeService(name).doY()
} yield Ack.Done
Cấp phép đặt tên cho phương thức là makeService
(và với một tham số nữa) sẽ làm cho nó khá rõ ràng phương thức đó làm gì và việc tái cấu trúc không phải là một điều an toàn để làm, nhưng "lý luận cục bộ" có nghĩa là bạn không cần phải xem tại các quy ước đặt tên và việc thực hiện makeService
để tìm ra: Bất kỳ biểu thức nào không thể xáo trộn một cách máy móc (bị lặp lại, lười biếng, háo hức, loại bỏ mã chết, song song, trì hoãn, lưu trữ, xóa khỏi bộ đệm, v.v.) mà không thay đổi hành vi ( tức là không "thuần") nên được gõ như hiệu quả.
delay
và trả về F [Dịch vụ] . Ví dụ, xemstart
phương thức trên IO , nó trả về IO [Fiber [IO ,?]] , Thay vì sợi đơn giản .