阅读此问题后:Functional proofs (Haskell)
在查看了Haskell音乐学院forall xs ys. length (xs ++ ys) = length xs + length ys
的归纳证明之后(第164页)。
在我看来,功能应用程序分配在列表连接上。
因此,更为一般的法律可能是forall f xs ys. f (xs ++ ys) = f xs ++ f ys
。
但是如何证明/反驳这样的谓词呢?
- 编辑 -
我写了一个错字:forall f xs ys. f (xs ++ ys) = f xs + f ys
,它与上一个问题和Haskell SoM使用的内容相匹配。话虽如此,由于这个错字,它已经不再是“分配”了#34;属性。然而,@ leftaroundabout为我原来的错字问题做出了正确答案。至于我的预期问题,法律仍然不正确,因为功能并不需要保留结构价值。 f
可能会给出完全不同的答案,具体取决于应用列表的长度。
答案 0 :(得分:8)
不,一般来说这显然不正确:
f [_] = []
f l = l
然后
f ([1] ++ [2]) = f [1,2] = [1,2]
但
f [1] ++ f [2] = [] ++ [] = []
我确信有这个问题的函数构成了一个有趣的类,但是一般函数可以对列表的结构做很多事情来阻止这样的不变量。
答案 1 :(得分:3)
在查看了Haskell音乐学院
forall xs ys. length (xs ++ ys) = length xs + length ys
的归纳证明之后(第164页)。在我看来,功能应用程序分配在列表连接上。
嗯,显然事实并非如此。例如:
reverse ([1..3] ++ [4..6]) /= reverse [1..3] ++ reverse [4..6]
您引用的示例是一个特殊情况,称为 monoid morphism :函数f :: m -> n
,以便:
m
和n
是具有二元操作<>
和身份mempty
的幺半群; f mempty = mempty
f (m <> m') == f m <> f m'
所以length :: [a] -> Int
是一个幺半形态,将[]
发送到0
,将++
发送到+
:
length [] = 0
length (xs ++ ys) = length xs + length ys