use*_*680 1 monads haskell functional-programming sum list
所以我在哈斯克尔身上愚弄,试着自己去学习.我正在尝试解决某个问题,我应该创建一个随机数列表然后总结它们.
我有生成它们的代码 - 使用getStdRandom和randomR.使用它们都返回一个列表IO Float:[IO Float]
现在,当我尝试使用say foldl或foldr总结列表,或者甚至尝试简单的递归求和时,我得到错误等等 - 据我所知这是因为IO Float是monad,所以我需要做一些Haskell魔法来获取它工作.
我一直在谷歌搜索,并没有找到有用的东西.
有没有办法总结清单?甚至将其转换为浮点列表,以便在代码的其他部分更容易解决?
请注意,类型的列表[IO Float]是没有号码的列表.它是生成数字的I/O操作列表.I/O尚未执行,因此在您的情况下,随机数生成器实际上并未生成数字.
您可以使用该sequence :: Monad m => [m a] -> m [a]功能将IO操作列表组合到一个提供结果列表的IO操作中:
do the_numbers <- sequence your_list
return $ sum the_numbers
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用该foldM函数编写一个monadic折叠:
sumIONumbers :: [IO Float] -> IO Float
sumIONumbers xs = foldM f 0.0 xs
where
f acc mVal = do
val <- mVal -- extract the Float from the IO
return $ acc + val
Run Code Online (Sandbox Code Playgroud)
如评论中所述,您还可以利用每个Monad都是Functor(这在较新版本中强制执行)的事实,因此您可以使用fmap :: Functor f => (a -> b) -> f a -> f b在IO中应用函数:
fmap sum (sequence your_list)
Run Code Online (Sandbox Code Playgroud)
或者使用中缀同义词<$>:
sum <$> sequence your_list
Run Code Online (Sandbox Code Playgroud)