我正在读《Programming in Scala》一书(红皮书(。
在关于 Monoid 的章节中,我了解了什么是 Monoid 同态,例如:具有串联和length
函数的字符串 MonoidM
f
保留了幺半群结构,因此是同态的。
M.op(f(x), f(y)) == M.op(f(x) + f(y))
// "Lorem".length + "ipsum".length == ("Lorem" + "ipsum").length
引用这本书(凭记忆,如果我错了,请纠正我:
当这种情况在两个方向上发生时,它被命名为幺半群同构,这意味着对于幺半群
M, N
,函数f, g
,f andThen g
和g andThen f
是identity
函数。例如,String
Monoid 和List[Char]
Monoid 具有串联是同构的。
但是我看不到看到这个的实际例子,我只能认为f
是length
函数,但是g
会发生什么?
注意:我看到了这个问题:什么是同构和同态。
要查看String
和List[Char]
之间的同构,我们有toList: String -> List[Char]
和mkString: List[Char] -> String
。
length
是从弦幺半群到自然数幺半群的同态,带有加法。
弦幺半群的内同态的几个例子是toUpperCase
和toLowerCase
。
对于列表,我们有很多同态,其中许多只是fold
的版本。
这是siyopao的答案,表示为ScalaCheck程序
object IsomorphismSpecification extends Properties("f and g") {
val f: String => List[Char] = _.toList
val g: List[Char] => String = _.mkString
property("isomorphism") = forAll { (a: String, b: List[Char]) =>
(f andThen g)(a) == a && (g andThen f)(b) == b
}
}
哪些输出
+ f and g.isomorphism: OK, passed 100 tests.