使用>> =运算符时约束中的非类型变量参数

Mar*_*olo 4 monads haskell functional-programming

我有这个简单的代码:

module Matrix where

matrix :: a -> (Int, Int) -> [[a]]
matrix x (width, height) = replicate height (replicate width x)

mapMatrix :: (a -> b) -> [[a]] -> [[b]]
mapMatrix f m = map (map f) m
Run Code Online (Sandbox Code Playgroud)

当我做:

mapMatrix (+1) (matrix 0 (2,2))
Run Code Online (Sandbox Code Playgroud)

我得到了,如预期的那样:

[[1,1],[1,1]]

可能我误解了monad和/或>>=运算符,但我希望以下内容具有相同的输出:

matrix 0 (2,2) >>= mapMatrix (+1)
Run Code Online (Sandbox Code Playgroud)

相反,我得到:

约束中的非类型变量参数:Num [b](使用FlexibleContexts允许此操作)当检查推断类型It :: forall b时.(Num [b],Num b)=> [[b]]

我怎么能用mapMatrix (+1) (matrix 0 (2,2))monad 写,所以我可以从左到右读取和编写代码而不是从内到外,因为你可以想象,我打算在mapMatrix同一个矩阵上使用很多东西,比如:

matrix ... >>= mapMatrix ... >>= mapMatrix .. >>= ...
Run Code Online (Sandbox Code Playgroud)

Ale*_*lec 5

这不是monad应该做的.您可能对(&) :: a -> (a -> b)定义的内容感兴趣Data.Function.

matrix ... & mapMatrix ... & mapMatrix .. & ...
Run Code Online (Sandbox Code Playgroud)

请注意绑定的签名是

(>>=) :: m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)

一个人不能简单地忽略ms.

为了完整性,请注意,实际上可以使绑定的行为几乎与您希望它使用一个特定monad的方式相同:Identity.它需要一些包装/展开构造函数.

module Matrix where

import Data.Functor.Identity

matrix :: a -> (Int, Int) -> Identity [[a]]
matrix x (width, height) = Identity $ replicate height (replicate width x)

mapMatrix :: (a -> b) -> [[a]] -> Identity [[b]]
mapMatrix f m = Identity $ map (map f) m
Run Code Online (Sandbox Code Playgroud)

然后,以下工作也是如此:

runIdentity (matrix ... >>= mapMatrix ... >>= mapMatrix .. >>= ...)
Run Code Online (Sandbox Code Playgroud)