简体   繁体   English

如何正确使用>> =替换此代码中的do和< - ?

[英]how to correctly use >>= to replace the do and <- in this code?

I have a question that goes on how to work with monads. 我有一个关于如何使用monad的问题。 I have the following code: 我有以下代码:

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 

and it works fine. 它工作正常。 However, I think its limiting to bind the output of getStdGen outside of randomW1 , and thought I could be able to bind the getStdGen more directly to randomW1 by writing 但是,我认为它限制的输出结合getStdGen之外randomW1 ,以为我可能是能够结合getStdGen直接更randomW1通过写作

w1 = take 50 (randomW1 =<< getStdGen) 

I believe I have utilised the >>= or =<< to "pipe" monadic structures together, and replacing the use of do and <- . 我相信我已经将>>==<< to“管”monadic结构一起使用,并取代了do<- When I am doing as I suggest I discover that it 我在做的时候,我建议我发现它

Couldn't match type ‘IO’ with ‘[]’
Expected type: [StdGen]
  Actual type: IO StdGen  

is there a way to use >>= to replace the do and <- in this code? 有没有办法在这段代码中使用>>=替换do<-

main = do  
    w1 <- getStdGen >>= (return . take 50 . randomW1)
    print w1 

(parentheses not actually needed) (实际上不需要括号)

Personally, I dislike the style above, since >>= (return . f) can be achieved with fmap f in a simpler way, as follows: 就个人而言,我不喜欢上面的风格,因为>>= (return . f) fmap f >>= (return . f)可以用fmap f以更简单的方式实现,如下所示:

main = do  
    w1 <- (take 50 . randomW1) `fmap` getStdGen
    -- or: w1 <- take 50 . randomW1 <$> getStdGen
    print w1 

Removing the last <- , we get: 删除最后一个<- ,我们得到:

main = print . take 50 . randomW1 =<< getStdGen

Here's a more systematic approach to derive the last one, step by step. 这是一个更系统的方法,逐步推导出最后一个。 Start from the beginning: 从头开始:

main = do  
    randomGen <- getStdGen
    let w1 = take 50 (randomW1 randomGen)
    print w1 

Inline w1 : 内联w1

main = do  
    randomGen <- getStdGen
    print (take 50 (randomW1 randomGen))

Desugar do x <- m ; e Desugar do x <- m ; e do x <- m ; e into m >>= \\x -> e . do x <- m ; em >>= \\x -> e This is how the do syntax is defined. 这就是do语法的定义方式。

main = getStdGen >>= \randomGen -> print (take 50 (randomW1 randomGen))

Use composition for the last lambda: 使用最后一个lambda的组合:

main = getStdGen >>= print . take 50 . randomW1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM