Rah*_*hul 1 algorithm monads haskell io-monad
我正在haskell上实现一些算法.该算法需要生成一些数据.
我有一个算法的功能,它将生成函数作为参数.例如,算法只是将输入数据乘以n:
algo :: a -> ??? -> [a]
algo n dgf = map (\x -> x * n) $ dgf
Run Code Online (Sandbox Code Playgroud)
dgf
用于生成数据.如何正确编写函数头,dgf
可以是任何具有任意数量参数的函数?
另一种变体是不接受生成函数但已经生成数据.
algo :: a -> [b] -> [a]
algo n d = (\x -> n*x) d
Run Code Online (Sandbox Code Playgroud)
那么,现在让我们想象一下我stdGen
使用IO 生成数据.如何使函数更通用,以便它可以同时接受IO实例和普通值[1,2,3]
.这也涉及具有功能的变体,因为它也可以产生IO.
总而言之,哪种解决方案更好 - 具有生成功能或预生成数据?
提前致谢.
一种选择是采用流而不是列表.如果生成值涉及执行IO
,并且可能有许多值,这通常是最好的方法.有几个包提供某种类型的流,但我将streaming
在此示例中使用该包.
import qualified Streaming.Prelude as S
import Streaming
algo :: Monad m => a -> Stream (Of a) m r -> Stream (Of a) m r
algo a = S.map (a +)
Run Code Online (Sandbox Code Playgroud)
您可以将其Stream (Of a) m r
视为"使用操作m
生成类型的连续值a
并最终生成类型结果的方法r
".此algo
函数不承诺生成数据的任何特定方式; 它们可以纯粹创建:
algo a (S.each [these, are, my, elements])
Run Code Online (Sandbox Code Playgroud)
或内IO
,
algo a $ S.takeWhile (> 3) (S.readLn :: Stream (Of Int) IO ())
Run Code Online (Sandbox Code Playgroud)
或使用随机monad,或任何你喜欢的.