关于 lambda:检查两个 Haskell 函数在非终止或错误方面是否相等

Check if two Haskell functions are equal with regards to non-termination or errors

我想知道,我两个 Haskell 函数是相等的,还要考虑执行导致错误或根本不终止的情况。

示例(这些函数都接受一个函数和一对作为参数,将函数应用于该对的两个成员,如果结果相同则返回 True,否则返回 False):

1
2
3
4
tupleEqual, tupleEqual' :: Eq b => (a -> b) -> (a, a) -> Bool
tupleEqual f = (\\(x,y) -> f x == f y)

tupleEqual' f (x, y) = f x == f y

我的问题是:我如何找出它们在未终止或错误的情况下的运行方式?

我知道第一个函数可以翻译成

1
tupleEqual f = let fun (x,y) = f x == f y in fun

这可能是相关的吗?


如果您想了解这两个函数在部分输入上的表现,您可以自己提供部分输入。对于一对(假设类型 (Int,Int)),关于偏性有四种不同的可能性。

1
2
3
4
( 1   , 1   ) -- Total
( _|_ , 1   ) -- Left bottom
( 1   , _|_ ) -- Right bottom
_|_           -- Bottom

您可以使用 undefined 作为底部值,并像在 ghci 中一样测试功能。我们将在这里测试 fst 函数作为示例:

1
2
3
4
5
6
7
8
>>> fst (1,1)
1
>>> fst (undefined,1)
undefined
>>> fst (1,undefined)
1
>>> fst undefined
undefined

所有这些都很明显,所以这里有一个更有趣的例子。

1
2
3
4
5
6
7
8
9
10
mapFst :: (a -> b) -> (a, c) -> (b, c)
mapFst f (x, y) = (f x, y)

mapFst' :: (a -> b) -> (a, c) -> (b, c)
mapFst' f xy = (f (fst xy), snd xy)

>>> fst (mapFst (const 1) undefined)
undefined
>>> fst (mapFst' (const 1) undefined)
1

你也可以用一个无可辩驳的模式 (~(x,y)) 来编写 mapFst'

最后,如果您想将此作为自动化测试框架的一部分进行测试,或者您只想更系统地进行测试,您可以使用 Chasing Bottoms 包。