在这里,我试图生成一个整数列表,我想在列表中添加随机数,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)
Run Code Online (Sandbox Code Playgroud)
错误发生在最后一行:
else return md:(fx (md-x) s)
Run Code Online (Sandbox Code Playgroud)
结果fx是在IOmonad中,并且结果你想要执行一个前置的纯操作md.这正是liftM你的最后一行应该是什么
else liftM (md :) (fx (md-x) s)
Run Code Online (Sandbox Code Playgroud)
其他小改进:
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)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)