【发布时间】:2017-04-07 00:12:14
【问题描述】:
我有这个简单的代码:
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]]
可能我误解了 monad 和/或 >>= 运算符,但我希望以下输出具有相同的输出:
matrix 0 (2,2) >>= mapMatrix (+1)
相反,我得到:
约束中的非类型变量参数:Num [b] (使用 FlexibleContexts 来允许这样做)检查推断类型时 它:: forall b。 (Num [b], Num b) => [[b]]
我如何用 monads 编写 mapMatrix (+1) (matrix 0 (2,2)),这样我就可以从左到右而不是从内到外读写代码,因为正如您所想象的那样,我正计划使用 mapMatrix a在同一个矩阵上很多,比如:
matrix ... >>= mapMatrix ... >>= mapMatrix .. >>= ...
【问题讨论】:
-
f x与x >>= f不同,正如f 1与1 + f不同:>>=是一个执行特定操作的运算符。 -
@amalloy 所以我使用了错误的运算符?我正在寻找的是经典的
bind操作,这是您在使用 monad 时获得的,至少在我用其他语言学习它们时是这样。顺便说一句,我这样做只是为了学习目的,但我现在真的可以使用一些指导 -
确实 >>= 是 monad 绑定操作,但 monad 绑定操作似乎不是您想要的。
-
嗯,我一直认为
bind为bind(x, f) <=> f(x)甚至x.bind(f) <=> f(x),我想我必须学习Haskell 的具体细节。 -
@MarcoScabbiolo 事实上,一般情况并非如此。也许您正在寻找
(&)(在Data.Function)?这被定义为x & f = f x。
标签: haskell functional-programming monads