【问题标题】:Non type-variable argument in the constraint when using >>= operator使用 >>= 运算符时约束中的非类型变量参数
【发布时间】: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 xx >>= f 不同,正如f 11 + f 不同:>>= 是一个执行特定操作的运算符。
  • @amalloy 所以我使用了错误的运算符?我正在寻找的是经典的bind 操作,这是您在使用 monad 时获得的,至少在我用其他语言学习它们时是这样。顺便说一句,我这样做只是为了学习目的,但我现在真的可以使用一些指导
  • 确实 >>= 是 monad 绑定操作,但 monad 绑定操作似乎不是您想要的。
  • 嗯,我一直认为bindbind(x, f) <=> f(x) 甚至x.bind(f) <=> f(x),我想我必须学习Haskell 的具体细节。
  • @MarcoScabbiolo 事实上,一般情况并非如此。也许您正在寻找(&)(在Data.Function)?这被定义为x & f = f x

标签: haskell functional-programming monads


【解决方案1】:

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

matrix ... & mapMatrix ... & mapMatrix .. & ...

注意bind的签名是

(>>=) :: m a -> (a -> m b) -> m b

而且不能简单地忽略ms。

为了完整起见,请注意实际上可以使用一个特定的 monad:Identity 使 bind 的行为几乎与您希望的一样。不过,它需要一些包装/展开构造函数。

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 .. >>= ...)

【讨论】:

  • 关于Identity 的注释在这里很重要,我通常用其他语言实现bind,使用bind 方法扩展本机根类型,我猜这使得根类型的行为有点像Identity monad 在您的示例中确实如此。这就是为什么每个人都应该尝试 Haskell,你会学到很多关于进行函数式编程的正确方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多