[英]Generating lists in a monadic context
As I understand, you can use the 'draw from' (<-)
keyword in haskell to take values out of a monadic context in do-notation: 据我了解,您可以在haskell中使用'draw from' (<-)
关键字从do-notation中的一元上下文中获取值:
func = do
x <- getRandom
let y = (x + 1)
return y
How would I apply this when generating lists? 生成列表时如何应用? Say I am mapping a function f :: (MonadRandom m) => Int -> ma
that takes an integer and returns a value in a MonadRandom
context. 假设我正在映射一个函数f :: (MonadRandom m) => Int -> ma
,它接受一个整数并在MonadRandom
上下文中返回一个值。 I want to generate a list of values of type a
inside a MonadRandom
context ie m [a]
. 我想在MonadRandom
上下文即m [a]
生成类型为a
的值的列表。 I believe doing something like this: 我相信这样做是这样的:
func = do
xs <- map f [0..10]
return xs
would generate a list of values, each in a monadic context and then try to draw from the list which is not in the MonadRandom
context 会生成一个值列表,每个值都在单子上下文中,然后尝试从不在MonadRandom
上下文中的列表中进行绘制
Apologies if my terminology/understanding is incorrect, I am new to haskell. 抱歉,如果我的术语/理解不正确,我是Haskell的新手。
for your edit with the MonadRandom I think all you need is mapM
: 对于MonadRandom的编辑,我认为您需要的只是mapM
:
import System.Random (randomRIO)
f :: Int -> IO Int
f n = randomRIO (n,n+n)
g :: [Int] -> IO [Int]
g xs = mapM f xs
example 例
λ> g [1..3]
[1,4,5]
λ> g [1..3]
[1,3,4]
λ> g [1..3]
[1,4,6]
btw: of course you can do this yourself using do
: 顺便说一句:当然,您可以使用do
自己执行此do
:
g :: [Int] -> IO [Int]
g [] = return []
g (x:xs) = do
r <- f x
rs <- g xs
return (r:rs)
just remember not to mix up the list and the IO
monad here - so the do
, <-
and return
here is in IO
- for the rest of this answer it will be in the list-monad 只是要记住不要在此处将列表和IO
monad混合在一起-因此, do
, <-
和此处return
在IO
-对于此答案的其余部分,它将在list-monad中
First your example (if f :: a -> [b]
) will create a list of list of values (which you surely found out already) - if you want to flatten it look below (basically you just have to pull out once more) 首先,您的示例(如果f :: a -> [b]
)将创建一个值列表的列表 (您肯定已经发现了)-如果您想将其展平到下面(基本上,您只需再次拉出) )
Right now I don't understand exactly where you are going for, but here is a short example of how you can use the do
notation with lists: 目前,我还不清楚您要去哪里,但是这里有一个简短的示例,说明如何将do
符号与列表一起使用:
Look at this function: 看一下这个功能:
combs :: [a] -> [b] -> [(a,b)]
combs xs ys = do
x <- xs
y <- ys
return (x,y)
here is an example of it in action: 这是一个实际的例子:
λ> combs [1..3] "Hi"
[(1,'H'),(1,'i'),(2,'H'),(2,'i'),(3,'H'),(3,'i')]
As you can see the trick is to draw an example x
out of all xs
(of course you will do all - therefore you can think of this as working with combinatorics) and a y
out of ys
and then do something with them (here just make a tuple) and finally return
ing it. 正如你所看到的, 关键是要画一个例子 x
掉所有的xs
(你当然会尽一切-所以你可以认为这与组合数学工作)和y
出来的ys
,然后做他们的东西(这里只是做一个元组),最后return
它。
Now of course you can first map it somehow (here just doubling the xs
): 现在,您当然可以先以某种方式对其进行映射了(这里只需将xs
加倍):
combs :: [a] -> [b] -> [(a,b)]
combs xs ys = do
x <- xs ++ xs
y <- ys
return (x,y)
and it will pull out of the mapped values: 它将拉出映射的值:
λ> combs [1..3] "Hi"
[(1,'H'),(1,'i'),(2,'H'),(2,'i'),(3,'H'),(3,'i'),(1,'H'),(1,'i'),(2,'H'),(2,'i'),(3,'H'),(3,'i')]
does this help you? 这对您有帮助吗?
here is another one where f
creates a list itself: 这是f
本身创建列表的另一个:
func :: (a -> [b]) -> [a] -> [b]
func f xs = do
x <- xs
b <- f x
return b
as you can see first we pull out an x
from xs
, apply f
to get a lists of b
s only to pull them out with b <- fx
and then just returning those. 如您所见,首先我们从xs
拉出一个x
,应用f
来获得b
s的列表,然后只用b <- fx
将它们拉出,然后返回它们。
Which is of course just concatMap
当然,这只是concatMap
λ> func (\x -> [x,x]) [1..5]
[1,1,2,2,3,3,4,4,5,5]
is this where you are going for? 这是您要去的地方吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.