使用 >>= 运算符时约束中的非类型变量参数
Non type-variable argument in the constraint when using >>= operator
我有这个简单的代码:
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
当我这样做时:
mapMatrix (+1) (matrix 0 (2,2))
我得到了,如预期的那样:
[[1,1],[1,1]]
可能我误解了 monads and/or 和 >>=
运算符,但我期望以下具有相同的输出:
matrix 0 (2,2) >>= mapMatrix (+1)
相反,我得到:
Non type-variable argument in the constraint: Num [b]
(Use FlexibleContexts to permit this) When checking the inferred type
It :: forall b. (Num [b], Num b) => [[b]]
如何使用 monad 编写 mapMatrix (+1) (matrix 0 (2,2))
,这样我就可以从左到右而不是从内到外读写代码,因为正如您所想象的,我正计划使用mapMatrix
很多在同一个矩阵上,比如:
matrix ... >>= mapMatrix ... >>= mapMatrix .. >>= ...
这不是 monad 应该做的。您可能对 Data.Function
中定义的 (&) :: a -> (a -> b)
感兴趣。
matrix ... & mapMatrix ... & mapMatrix .. & ...
注意bind的签名是
(>>=) :: m a -> (a -> m b) -> m b
而且不能简单地忽略 m
s。
为了完整起见,请注意实际上 可以 使用一个特定的 monad:Identity
使 bind 的行为几乎与您希望的一样。不过,它需要一些 wrapping/unwrapping 构造函数。
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
那么,下面的方法也有效:
runIdentity (matrix ... >>= mapMatrix ... >>= mapMatrix .. >>= ...)
我有这个简单的代码:
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
当我这样做时:
mapMatrix (+1) (matrix 0 (2,2))
我得到了,如预期的那样:
[[1,1],[1,1]]
可能我误解了 monads and/or 和 >>=
运算符,但我期望以下具有相同的输出:
matrix 0 (2,2) >>= mapMatrix (+1)
相反,我得到:
Non type-variable argument in the constraint: Num [b] (Use FlexibleContexts to permit this) When checking the inferred type It :: forall b. (Num [b], Num b) => [[b]]
如何使用 monad 编写 mapMatrix (+1) (matrix 0 (2,2))
,这样我就可以从左到右而不是从内到外读写代码,因为正如您所想象的,我正计划使用mapMatrix
很多在同一个矩阵上,比如:
matrix ... >>= mapMatrix ... >>= mapMatrix .. >>= ...
这不是 monad 应该做的。您可能对 Data.Function
中定义的 (&) :: a -> (a -> b)
感兴趣。
matrix ... & mapMatrix ... & mapMatrix .. & ...
注意bind的签名是
(>>=) :: m a -> (a -> m b) -> m b
而且不能简单地忽略 m
s。
为了完整起见,请注意实际上 可以 使用一个特定的 monad:Identity
使 bind 的行为几乎与您希望的一样。不过,它需要一些 wrapping/unwrapping 构造函数。
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
那么,下面的方法也有效:
runIdentity (matrix ... >>= mapMatrix ... >>= mapMatrix .. >>= ...)