Tôi có một hàm đơn giản sử dụng Control.Monad.Random
để tạo một hàm có thể lấy mẫu một số ngẫu nhiên.Kết hợp RandT và MaybeT
import Control.Monad.Random
import Data.Random
unif_bound :: (RandomGen g, Monad m) => Double -> Double -> RandT g m Double
unif_bound lb ub = getRandomR (lb,ub)
Và, tôi chạy này để tạo số ngẫu nhiên trong GHCI như:
> gen <- newStdGen
> runRandT (unif_bound 1.0 3.0) gen
(1.7569726469904563,1700403094 44073136)
> runRandT (unif_bound 3.0, 1.0) gen
(1.7569726469904563,1700403094 44073136)
Tuy nhiên, tôi muốn thay đổi mã này để kiểm tra xem lb < ub
, và bọc này trong một MaybeT. Ý tưởng là lấy mẫu nơi lb > ub
phải trả lại Nothing
. Tôi nhận ra rằng đây là nơi mà các biến thế đơn nguyên xuất hiện, nhưng tôi chưa bao giờ sử dụng một cái trước và không chắc chắn nên bắt đầu từ đâu.
Để tham khảo, RandT
được định nghĩa là
-- | A monad transformer which adds a random number generator to an
-- existing monad.
newtype RandT g m a = RandT (StateT g m a)
deriving (Functor, Monad, MonadTrans, MonadIO, MonadFix, MonadReader r, MonadWriter w)
Cảm ơn!
http://en.wikibooks.org/wiki/Haskell/Monad_transformers. Bạn cũng có thể chỉ cần trả lại một 'RandT g m (Có thể đôi)' - máy biến áp đôi khi quá mức cần thiết, và âm thanh như họ có thể là dành cho trường hợp của bạn. Nhưng một cơ hội tốt để học hỏi! – luqui