簡體   English   中英

在單子上下文中生成列表

[英]Generating lists in a monadic context

據我了解,您可以在haskell中使用'draw from' (<-)關鍵字從do-notation中的一元上下文中獲取值:

func = do
    x <- getRandom
    let y = (x + 1)
    return y

生成列表時如何應用? 假設我正在映射一個函數f :: (MonadRandom m) => Int -> ma ,它接受一個整數並在MonadRandom上下文中返回一個值。 我想在MonadRandom上下文即m [a]生成類型為a的值的列表。 我相信這樣做是這樣的:

func = do
    xs <- map f [0..10]
    return xs

會生成一個值列表,每個值都在單子上下文中,然后嘗試從不在MonadRandom上下文中的列表中進行繪制

抱歉,如果我的術語/理解不正確,我是Haskell的新手。

更新

對於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

λ> g [1..3]
[1,4,5]
λ> g [1..3]
[1,3,4]
λ> g [1..3]
[1,4,6]

順便說一句:當然,您可以使用do自己執行此do

g :: [Int] -> IO [Int]
g [] = return []
g (x:xs) = do
  r <- f x
  rs <- g xs
  return (r:rs)

只是要記住不要在此處將列表和IO monad混合在一起-因此, do<-和此處returnIO -對於此答案的其余部分,它將在list-monad中


首先,您的示例(如果f :: a -> [b] )將創建一個值列表的列表 (您肯定已經發現了)-如果您想將其展平到下面(基本上,您只需再次拉出) )


目前,我還不清楚您要去哪里,但是這里有一個簡短的示例,說明如何將do符號與列表一起使用:

看一下這個功能:

combs :: [a] -> [b] -> [(a,b)]
combs xs ys = do
  x <- xs
  y <- ys
  return (x,y)

這是一個實際的例子:

λ> combs [1..3] "Hi"
[(1,'H'),(1,'i'),(2,'H'),(2,'i'),(3,'H'),(3,'i')]

正如你所看到的, 關鍵是要畫一個例子 x掉所有的xs (你當然會盡一切-所以你可以認為這與組合數學工作)和y出來的ys ,然后做他們的東西(這里只是做一個元組),最后return它。

現在,您當然可以先以某種方式對其進行映射了(這里只需將xs加倍):

combs :: [a] -> [b] -> [(a,b)]
combs xs ys = do
  x <- xs ++ xs
  y <- ys
  return (x,y)

它將拉出映射的值:

λ> 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')]

這對您有幫助嗎?


這是f本身創建列表的另一個:

func :: (a -> [b]) -> [a] -> [b]
func f xs = do
  x <- xs
  b <- f x
  return b

如您所見,首先我們從xs拉出一個x ,應用f來獲得b s的列表,然后只用b <- fx將它們拉出,然后返回它們。

當然,這只是concatMap

λ> func (\x -> [x,x]) [1..5]
[1,1,2,2,3,3,4,4,5,5]

這是您要去的地方嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM