Tôi đang cố viết một trò chơi nhỏ trong Haskell và có một số lượng trạng thái cần thiết để vượt qua. Tôi muốn thử che giấu tiểu bang bằng đơn vị Tiểu bangSử dụng trình đơn trạng thái để ẩn trạng thái rõ ràng
Bây giờ tôi đã gặp phải vấn đề: các chức năng đưa tiểu bang và tranh luận trở nên dễ dàng để viết để làm việc trong tiểu bang. Nhưng cũng có các hàm chỉ lấy trạng thái làm đối số (và trả về trạng thái đã sửa đổi, hoặc có thể là một cái gì đó khác).
Trong một phần của mã của tôi, tôi có dòng này:
let player = getCurrentPlayer state
Tôi muốn nó để không phải đi tiểu bang, và thay vì viết
player <- getCurrentPlayerM
hiện nay, việc thực hiện nó trông như thế này
getCurrentPlayer gameState =
(players gameState) ! (on_turn gameState)
và dường như đủ đơn giản để làm cho nó hoạt động trong đơn nguyên trạng thái bằng cách viết nó như sau:
getCurrentPlayerM = do state <- get
return (players state ! on_turn state)
Tuy nhiên, điều đó gây nên khiếu nại từ ghc! Không có trường hợp nào (MonadState GameState m0) phát sinh từ việc sử dụng `get ', nó nói. Tôi đã viết lại một chức năng rất giống nhau, ngoại trừ việc không nullary ở dạng đơn nguyên nhà nước của Bộ, vì vậy trên một linh cảm, tôi viết lại nó như thế này:
getCurrentPlayerM _ = do state <- get
return (players state ! on_turn state)
Và chắc chắn đủ, nó hoạt động! Nhưng tất nhiên tôi phải gọi nó là getCurrentPlayerM(), và tôi cảm thấy một chút ngớ ngẩn khi làm điều đó. Đi qua trong một cuộc tranh luận là những gì tôi muốn tránh ngay từ đầu!
Một ngạc nhiên khác: nhìn vào loại của nó trong ghci tôi nhận được
getCurrentPlayerM :: MonadState GameState m => t -> m P.Player
nhưng nếu tôi cố gắng thiết lập mà rõ ràng trong mã của tôi, tôi nhận được một lỗi: "Không loại biến lập luận trong ràng buộc MonadState GameState m "và một lời đề nghị của một phần mở rộng ngôn ngữ để cho phép nó. Tôi cho rằng đó là vì GameState của tôi là một loại và không phải là một kiểu chữ, nhưng tại sao nó được chấp nhận trong thực tế nhưng không phải khi tôi cố gắng rõ ràng về nó, tôi thấy bối rối hơn.
Vì vậy, để tổng hợp:
- Tại sao tôi không thể viết các hàm nullary trong đơn nguyên nhà nước?
- Tại sao tôi không thể khai báo loại chức năng workaround của tôi thực sự có?
Hiển thị rõ ràng đơn nguyên mà tôi muốn có vẻ là giải pháp đúng trong trường hợp của tôi. Có, tôi đã chạy vào vấn đề với các hồ sơ trong hồ sơ, và đọc một chút về Ống kính (trong số những thứ khác, khi tôi tìm kiếm câu trả lời ở đây, nó dường như được đề nghị rất nhiều!). Cảm ơn, giải thích tuyệt vời! –