如何正确使用 >>= 替换这段代码中的 do 和 <- ?
how to correctly use >>= to replace the do and <- in this code?
我有一个关于如何使用 monad 的问题。我有以下代码:
import System.Random
import Data.Random.Normal
import Graphics.EasyPlot
import Data.List
import Data.Function
random' mean randomGen = zip x y
where
x = normals' (mean, 0.2) randomGen :: [Float]
y = normals' (mean, 0.2) randomGen :: [Float]
randomW1 randomGen = [[x,y] | (x,y) <- random' 1.0 randomGen]
main = do
randomGen <- getStdGen
let w1 = take 50 (randomW1 randomGen)
print w1
而且效果很好。但是,我认为它限制了将 getStdGen
的输出绑定到 randomW1
之外,并且我认为我可以通过编写 [=] 将 getStdGen
更直接地绑定到 randomW1
24=]
w1 = take 50 (randomW1 =<< getStdGen)
我相信我已经将 >>=
或 =<<
与 "pipe" 单子结构一起使用,并替换了 do
和 <-
的使用。当我按照我的建议去做时,我发现它
Couldn't match type ‘IO’ with ‘[]’
Expected type: [StdGen]
Actual type: IO StdGen
有没有办法用>>=
代替这段代码中的do
和<-
?
main = do
w1 <- getStdGen >>= (return . take 50 . randomW1)
print w1
(实际上不需要括号)
个人不喜欢上面的样式,因为>>= (return . f)
可以用fmap f
实现,更简单的方法如下:
main = do
w1 <- (take 50 . randomW1) `fmap` getStdGen
-- or: w1 <- take 50 . randomW1 <$> getStdGen
print w1
删除最后一个 <-
,我们得到:
main = print . take 50 . randomW1 =<< getStdGen
这里有一个更系统的方法来推导最后一个,一步一步。从头开始:
main = do
randomGen <- getStdGen
let w1 = take 50 (randomW1 randomGen)
print w1
内联w1
:
main = do
randomGen <- getStdGen
print (take 50 (randomW1 randomGen))
将 do x <- m ; e
脱糖为 m >>= \x -> e
。这就是 do
语法的定义方式。
main = getStdGen >>= \randomGen -> print (take 50 (randomW1 randomGen))
对最后一个 lambda 使用组合:
main = getStdGen >>= print . take 50 . randomW1
我有一个关于如何使用 monad 的问题。我有以下代码:
import System.Random
import Data.Random.Normal
import Graphics.EasyPlot
import Data.List
import Data.Function
random' mean randomGen = zip x y
where
x = normals' (mean, 0.2) randomGen :: [Float]
y = normals' (mean, 0.2) randomGen :: [Float]
randomW1 randomGen = [[x,y] | (x,y) <- random' 1.0 randomGen]
main = do
randomGen <- getStdGen
let w1 = take 50 (randomW1 randomGen)
print w1
而且效果很好。但是,我认为它限制了将 getStdGen
的输出绑定到 randomW1
之外,并且我认为我可以通过编写 [=] 将 getStdGen
更直接地绑定到 randomW1
24=]
w1 = take 50 (randomW1 =<< getStdGen)
我相信我已经将 >>=
或 =<<
与 "pipe" 单子结构一起使用,并替换了 do
和 <-
的使用。当我按照我的建议去做时,我发现它
Couldn't match type ‘IO’ with ‘[]’
Expected type: [StdGen]
Actual type: IO StdGen
有没有办法用>>=
代替这段代码中的do
和<-
?
main = do
w1 <- getStdGen >>= (return . take 50 . randomW1)
print w1
(实际上不需要括号)
个人不喜欢上面的样式,因为>>= (return . f)
可以用fmap f
实现,更简单的方法如下:
main = do
w1 <- (take 50 . randomW1) `fmap` getStdGen
-- or: w1 <- take 50 . randomW1 <$> getStdGen
print w1
删除最后一个 <-
,我们得到:
main = print . take 50 . randomW1 =<< getStdGen
这里有一个更系统的方法来推导最后一个,一步一步。从头开始:
main = do
randomGen <- getStdGen
let w1 = take 50 (randomW1 randomGen)
print w1
内联w1
:
main = do
randomGen <- getStdGen
print (take 50 (randomW1 randomGen))
将 do x <- m ; e
脱糖为 m >>= \x -> e
。这就是 do
语法的定义方式。
main = getStdGen >>= \randomGen -> print (take 50 (randomW1 randomGen))
对最后一个 lambda 使用组合:
main = getStdGen >>= print . take 50 . randomW1