我遇到了 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/