let vs do 在一元值中
let vs do in monadic values
尝试使用 monadic 值时使用 let
或 do
有什么区别? (不确定这是否是正确的表达方式)
例如:
--import System.Random
*Main> dupRand = let i = randomRIO (1, 10) in sequence [i, i]
*Main> :t dupRand
dupRand :: (Random a, Num a) => IO [a]
*Main> dupRand
[8,3]
*Main> dupRand
[2,9]
*Main> dupRand
[9,5]
*Main> dupRand2 = do i <- randomRIO (1, 10); pure [i, i]
*Main> :t dupRand2
dupRand2 :: (Random a, Num a) => IO [a]
*Main> dupRand2
[6,6]
*Main> dupRand2
[9,9]
*Main> dupRand2
[5,5]
为什么在dupRand2
中,函数成功复制了一个随机值,而在dupRand
中,函数似乎生成了两个随机值?
在
dupRand =
let i = randomRIO (1, 10)
in sequence [i, i]
您将 i
绑定到一个 IO
操作,当 运行 时,该操作将产生一个随机数。您制作了一个包含两个元素的列表,每个元素都包含该操作。现在
sequence
:: (Traversable t, Monad m)
=> t (m a) -> m (t a)
在此上下文中,Traversable
为 []
,Monad
为 IO
,因此
sequence :: [IO a] -> IO [a]
它的作用是 运行 列表中的每个 IO
操作,按顺序返回它们的结果列表。所以当我们运行sequence [i, i]
时,我们得到一个随机数,得到一个随机数,然后产生一个包含它们的列表。
dupRand2
不进行类型检查。我猜你的意思是
dupRand2 = do
i <- randomRIO (1, 10)
pure [i, i]
这是
的语法糖
dupRand2 =
randomRIO (1, 10) >>= \i ->
pure [i, i]
当 运行 时,此操作将 i
绑定到一个随机数(而不是生成随机数的操作),然后 returns 一个包含 i
的列表重复两次。
尝试使用 monadic 值时使用 let
或 do
有什么区别? (不确定这是否是正确的表达方式)
例如:
--import System.Random
*Main> dupRand = let i = randomRIO (1, 10) in sequence [i, i]
*Main> :t dupRand
dupRand :: (Random a, Num a) => IO [a]
*Main> dupRand
[8,3]
*Main> dupRand
[2,9]
*Main> dupRand
[9,5]
*Main> dupRand2 = do i <- randomRIO (1, 10); pure [i, i]
*Main> :t dupRand2
dupRand2 :: (Random a, Num a) => IO [a]
*Main> dupRand2
[6,6]
*Main> dupRand2
[9,9]
*Main> dupRand2
[5,5]
为什么在dupRand2
中,函数成功复制了一个随机值,而在dupRand
中,函数似乎生成了两个随机值?
在
dupRand =
let i = randomRIO (1, 10)
in sequence [i, i]
您将 i
绑定到一个 IO
操作,当 运行 时,该操作将产生一个随机数。您制作了一个包含两个元素的列表,每个元素都包含该操作。现在
sequence
:: (Traversable t, Monad m)
=> t (m a) -> m (t a)
在此上下文中,Traversable
为 []
,Monad
为 IO
,因此
sequence :: [IO a] -> IO [a]
它的作用是 运行 列表中的每个 IO
操作,按顺序返回它们的结果列表。所以当我们运行sequence [i, i]
时,我们得到一个随机数,得到一个随机数,然后产生一个包含它们的列表。
dupRand2
不进行类型检查。我猜你的意思是
dupRand2 = do
i <- randomRIO (1, 10)
pure [i, i]
这是
的语法糖dupRand2 =
randomRIO (1, 10) >>= \i ->
pure [i, i]
当 运行 时,此操作将 i
绑定到一个随机数(而不是生成随机数的操作),然后 returns 一个包含 i
的列表重复两次。