monad相关性定律中的未绑定变量

Leo*_*o D 1 monads closures haskell associativity

使用ghci我计算:

Prelude> let m = [1,2]
Prelude> let ys = [4, 5, 6]
Prelude> m >>= (\x -> ys >>= (\y -> return (x, y)))
[(1,4),(1,5),(1,6),(2,4),(2,5),(2,6)]
Run Code Online (Sandbox Code Playgroud)

上面的monadic表达似乎不符合monad关联性法则的任何一方:

(m >>= f) >>= g ? m >>= (\x -> f x >>= g)
Run Code Online (Sandbox Code Playgroud)

我想知道monad关联性如何应用于表达式:

m >>= (\x -> ys >>= (\y -> return (x, y))) 
Run Code Online (Sandbox Code Playgroud)

因为return (x,y)关闭周围的函数和包含它的那个函数,似乎在关联性定律的左侧存在的中间monad (m >>= f)在这个例子中不存在.

Aad*_*hah 7

我认为你对monadic表达的结构混淆了monadic定律.monadic关联性法则规定表达式(m >>= f) >>= g必须等同于被认为是monad m >>= (\x -> f x >>= g)的数据类型的表达式m.

这并不意味着每个monadic表达式都必须是这种形式(m >>= f) >>= g.

例如,m >>= f即使它不是形式,也是一个完全有效的monadic表达式(m >>= f) >>= g.然而,它仍然遵守一元联合法,因为m可以扩展到m >>= return(来自一元权利身份法m >>= return ? m).因此:

m >>= f

-- is equivalent to

(m >>= return) >>= f

-- is of the form

(m >>= f) >>= g
Run Code Online (Sandbox Code Playgroud)

在您的示例m >>= (\x -> ys >>= (\y -> return (x, y)))中,表单的m >>= f位置f是\x -> ys >>= (\y -> return (x, y)).

虽然\x -> ys >>= (\y -> return (x, y))不是形式\x -> f x >>= g(从一元联合法的右边),但并不意味着它违反了一元法则.

表达m >>= (\x -> ys >>= (\y -> return (x, y)))可以通过用被扩展到一元关联形式m >>= return为m:

(m >>= return) >>= (\x -> ys >>= (\y -> return (x, y)))

-- is of the form

(m >>= f) >>= g

-- and can be written as

m >>= (\x -> return x >> (\x -> ys >>= (\y -> return (x, y))))
Run Code Online (Sandbox Code Playgroud)

希望澄清事情.