List 需要解释基本do块语法吗
在ghci中,我写道:List 需要解释基本do块语法吗,list,haskell,list-comprehension,monads,do-notation,List,Haskell,List Comprehension,Monads,Do Notation,在ghci中,我写道: let x = do i <- [1..5] j <- [2..4] return i 实际结果: [1,1,1,2,2,2,3,3,3,4,4,4,5,5,5] 我不理解输出背后的逻辑。我想原因可能与monad有关,但我对函数式编程非常陌生,我希望有人能解释一下 我还尝试了列表理解中的等价形式,结果是一样的,这意味着我在这里误解了一些基本的东西。这是因为do机制(幸运的)不关心最里面的代码是否实际引用(某些)循环变量 请注意,
let x = do
i <- [1..5]
j <- [2..4]
return i
实际结果:
[1,1,1,2,2,2,3,3,3,4,4,4,5,5,5]
我不理解输出背后的逻辑。我想原因可能与monad有关,但我对函数式编程非常陌生,我希望有人能解释一下
我还尝试了列表理解中的等价形式,结果是一样的,这意味着我在这里误解了一些基本的东西。这是因为do机制(幸运的)不关心最里面的代码是否实际引用(某些)循环变量 请注意,无论最里面的代码如何,始终会得到3*5=15的值:
λ>
λ> xs1 = do { i <- [1..5] ; j <- [2..4] ; return i }
λ> xs1
[1,1,1,2,2,2,3,3,3,4,4,4,5,5,5]
λ>
λ> xs2 = do { i <- [1..5] ; j <- [2..4] ; return 9 }
λ> xs2
[9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]
λ>
λ> xs3 = do { i <- [1..5] ; j <- [2..4] ; return (i,j) }
λ> xs3
[(1,2),(1,3),(1,4),(2,2),(2,3),(2,4),(3,2),(3,3),(3,4),(4,2),(4,3),(4,4),(5,2),(5,3),(5,4)]
λ>
λ> length xs1
15
λ> length xs2
15
λ> length xs3
15
λ>
我也尝试过列表理解中的等价形式,结果是一样的
好主意。对于列表,do
表示法的作用恰好与列表理解相同。(事实上,有一种方法允许您对任何monad使用列表理解符号,就像您可以对任何monad使用do
符号一样。)
因此,您会问为什么
[a | aIf您熟悉命令式语言的编程,这与嵌套for循环相当。否则,您可以查看如何执行语法、如何处理defns等。请尝试[(i,0)|我觉得语法很简单。你的问题是你不理解列表monad是如何工作的。注意,.related:。(我知道“depens-on”是公认的行话,但实际上不清楚它的意思。使用“reference-to”可能更清楚;也可以使用xs1=do{谢谢你这么详细的解释!@WillNess-获得了分数,谢谢。不过我还是喜欢保持第一个例子的原样,因为这是从OP的问题文本中逐字记录下来的。是的,因此是“附加的”。(我认为(i,0)比一些随机值更好地显示了它的结构。)
λ>
λ> xs1 = do { i <- [1..5] ; j <- [2..4] ; return i }
λ> xs1
[1,1,1,2,2,2,3,3,3,4,4,4,5,5,5]
λ>
λ> xs2 = do { i <- [1..5] ; j <- [2..4] ; return 9 }
λ> xs2
[9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]
λ>
λ> xs3 = do { i <- [1..5] ; j <- [2..4] ; return (i,j) }
λ> xs3
[(1,2),(1,3),(1,4),(2,2),(2,3),(2,4),(3,2),(3,3),(3,4),(4,2),(4,3),(4,4),(5,2),(5,3),(5,4)]
λ>
λ> length xs1
15
λ> length xs2
15
λ> length xs3
15
λ>
#include <vector>
#include <iostream>
int main()
{
std::vector<int> vi{1,2,3,4,5};
std::vector<int> vj{2,3,4};
for (int i: vi)
for (int j: vj)
std::cout << i << ", ";
std::cout << std::endl;
return EXIT_SUCCESS;
}
$ ./a.out
1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5,
$
[x | x <- [0,1,0]]