arrays - 矩阵作为应用仿函数,不是 Monad

标签 arrays scala monads applicative category-theory

我遇到了 examples不是 Monad 的应用程序。我喜欢多维数组示例,但我没有完全理解它。

让我们采用矩阵M[A]。你能用 Scala 代码证明 M[A] 是一个 Applicative 而不是一个 Monad 吗?您有任何将矩阵用作 Applicatives 的“真实世界”示例吗?

最佳答案

类似于 M[T] <*> M[T => U]适用性:

val A = [[1,2],[1,2]] //let's assume such imaginary syntax for arrays
val B = [[*2, *3], [*5, *2]]

A <*> B === [[2,6],[5,4]]

例如,信号处理中可能有更复杂的应用程序。使用应用程序允许您构建一个函数矩阵(每个函数执行 N 次或更少的元素运算)并且仅执行 1 次矩阵运算而不是 N 次。

根据定义,矩阵不是幺半群 - 您必须为此在矩阵之间定义“+”(串联)(更准确地说是 fold)。并不是每个(甚至是幺半群的)矩阵都是单子(monad)——你必须另外定义 fmap (不是 flatMap - 只是 map 在 scala 中)使它成为 Functor (如果它返回矩阵,则为内仿函数)。但默认情况下 Matrix 不是 Functor/Monoid/Monad(Functor + Monoid)。

关于一元矩阵。矩阵可以是幺半群:您可以为沿正交维度大小相同的矩阵定义维度绑定(bind)串联。与维度/大小无关的串联将类似于:

val A = [[11,12],[21,22]]; val B = [[11,12,13],[21,22,23],[31,32,33]]
A + B === [[11,12,0,0,0], [21,22,0,0,0], [0,0,11,12,13],[0,0,21,22,23],[0,0,31,32,33]

标识元素将为 []

所以你也可以构建 monad(又是伪代码):

def flatMap[T, U](a: M[T])(f: T => M[U]) = {
    val mapped = a.map(f)// M[M[U]] // map
    def normalize(xn: Int, yn: Int) = ... // complete matrix with zeros to strict xn * yn size
    a.map(normalize(a.max(_.xn), a.max(_.yn)))
     .reduceHorizontal(_ concat _)
     .reduceVertical(_ concat _) // flatten
}

val res = flatMap([[1,1],[2,1]], x => if(x == 1)[[2,2]] else [[3,3,3]])

res === [[2,2,0,2,2],[3,3,3,2,2]]

不幸的是,对于 T(不仅是幺半群本身),您必须具有零元素(或任何默认值)。它不会使 T 本身成为某种岩浆(因为不需要为此集合定义二进制操作 - 只需要为 T 定义一些 const),但可能会产生其他问题(取决于您的挑战)。

关于arrays - 矩阵作为应用仿函数,不是 Monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27363061/

相关文章:

c++ - C++ 中的 LU 分解

scala - 如何替换通用匿名函数?

html - 事件源和 Internet Explorer

functional-programming - monad 除了提高可读性和生产力之外还有其他作用吗?

scala - 将许多 Either 映射到一个 Either 与许多

haskell - 嵌套的迭代器

php - 根据值对二维数组进行分组

arrays - 如何在 Ruby 中将数组转换为另一个数组

php - 如何在响应中返回数组

Scalacheck Prop 类型不匹配