Tôi đang viết một số mã (bộ lấy mẫu MCMC của Metropolis-Hastings) sẽ sử dụng trình tạo số ngẫu nhiên và sửa đổi một mảng và các cấu trúc khác có khả năng dựa trên điều này.Cách tốt nhất để theo dõi một số tham chiếu giữa các hàm trong ST monad?
Ý tưởng ban đầu của tôi là sử dụng đơn ST, để tôi có thể sử dụng các mảng ST và gói mersenne-random-pure64, giữ bộ tạo PureMT như một phần của trạng thái.
Tuy nhiên tôi muốn có thể tách một số công việc thành các hàm trợ giúp riêng biệt (ví dụ: lấy mẫu một số nguyên ngẫu nhiên trong một phạm vi nhất định, để cập nhật cấu trúc mảng và những thứ phức tạp hơn). Để làm điều này, tôi nghĩ rằng tôi sẽ cần phải chuyển các tham chiếu đến gen PureMT và mảng tới tất cả các hàm, mà có thể nhanh chóng trở nên rất xấu nếu tôi cần lưu trữ nhiều trạng thái hơn. Bản năng của tôi là nhóm tất cả trạng thái thành một kiểu dữ liệu duy nhất mà tôi có thể truy cập ở bất cứ nơi nào, vì tôi sẽ sử dụng đơn vị trạng thái bằng cách xác định một kiểu dữ liệu mới, nhưng tôi không biết liệu có thể với ST đó hay không. monad, hoặc đúng cách để đi về nó.
Có mẫu nào hay để làm việc này không? Tôi muốn giữ mọi thứ càng chung càng tốt bởi vì tôi có thể sẽ cần thêm trạng thái phụ và xây dựng thêm mã đơn điệu xung quanh các phần hiện có.
Tôi đã thử tìm kiếm các ví dụ về mã mon đơn ST nhưng nó dường như không được đề cập trong Real World Haskell và các ví dụ wiki haskell rất ngắn và đơn giản.
cảm ơn!
Điều này nghe có vẻ như một ý tưởng hay, tôi quên rằng các tham chiếu không thực sự thay đổi. Cám ơn vì cái này! Tôi cũng tự hỏi về việc có thể sử dụng ST monad từ bên trong chính nó để tách các tính toán trạng thái độc lập đang chạy trong môi trường mức cao hơn mà họ không cần truy cập, với trạng thái cục bộ ẩn của riêng chúng. Tôi có cần phải sử dụng biến áp ST monad cho điều này, hoặc bạn có thể chỉ cần sử dụng let a = runST $ .... bên trong ST monad? Nếu bạn có thể (mà không sử dụng máy biến áp) điều gì sẽ xảy ra nếu bạn cố gắng dereference một ref từ các đơn nguyên kèm theo (giả sử họ sẽ có trong phạm vi)? – Tom
@Tom: Không có biến áp nào cho 'ST' - như' IO', nó luôn ở dưới cùng của bất kỳ ngăn xếp nào. Hơn nữa, bất kỳ hai phép tính 'ST' hoàn chỉnh nào - tức là, những thứ xảy ra bên trong một cuộc gọi tới' runST' - hoàn toàn tách biệt khỏi trạng thái của nhau, và bất kỳ nỗ lực trộn nào chúng sẽ đưa ra một lỗi kiểu. Bạn có thể vượt qua các giá trị mờ đục xung quanh, giống như bạn có thể truyền 'IORef' '' '' '' '' 'bên trong' ST', nhưng bạn không thể sử dụng * chúng nhiều hơn bạn có thể sử dụng 'IORef'. Bạn có thể sử dụng 'runST' giống như bình thường, mặc dù; kết quả của điều đó là một giá trị thuần túy, như mọi khi. –
@Tom: Ngoài ra, nếu bạn sử dụng 'ReaderT' như trong ví dụ của tôi, bạn có thể thực hiện một số loại hoạt động của khung mà không gặp quá nhiều rắc rối - nhân bản môi trường hiện tại để chạy trong một' ST' riêng biệt bên trong, chạy một cái gì đó trong cùng 'ST' với môi trường khác, & c. –