这里我试图生成一个整数列表,我希望在不满足md<=1
的条件下向列表中添加随机数。
我试了好几次但没有运气。
fx :: Int -> Int -> IO [Int]
fx md s = do
x <- randomRIO (1,min md s)
if md<=1
then return [md]
else return md:(fx (md-x) s)
答案 0 :(得分:9)
错误发生在最后一行:
else return md:(fx (md-x) s)
fx
的结果位于IO
monad中,因此您希望执行纯md
前置操作。这正是liftM
所做的,你的最后一行应该是
else liftM (md :) (fx (md-x) s)
其他小改进:
IO
,你只需要在函数中生成随机数。为此,您可以使用MonadRandom
类型类(驻留在具有相同名称的包中)。这将使功能更具体,类型安全和灵活。md <= 1
根本不需要x
。因此,改进后的版本可能如下所示:
import Control.Monad
import Control.Monad.Random
fx :: (MonadRandom m) => Int -> Int -> m [Int]
fx md s | md <= 1 = return [md]
| otherwise = do
x <- getRandomR (1, min md s)
liftM (md :) (fx (md-x) s)
liftM
也许这更容易理解:
fx :: (MonadRandom m) => Int -> Int -> m [Int]
fx md s | md <= 1 = return [md]
| otherwise = do
x <- getRandomR (1, min md s)
xs <- fx (md-x) s
return (md : xs)