【问题标题】:Check if two Haskell functions are equal with regards to non-termination or errors检查两个 Haskell 函数在非终止或错误方面是否相等
【发布时间】:2019-11-24 12:40:22
【问题描述】:

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

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

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

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

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

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

这可能是相关的吗?

【问题讨论】:

  • 您是否要求确定函数是否终止?这是停止问题,众所周知,它是不可判定的——没有算法可以实现这一点。 en.wikipedia.org/wiki/Halting_problem
  • 我明白了。我只是想知道如何检查两个函数是否相等。例如,如果我使用 lambda 抽象,它会有所不同吗?例如,关于编译器如何处理不终止输入的函数?
  • 两个任意函数的等价可以是reduced to halting problem,所以也是不可判定的

标签: haskell lambda functional-programming


【解决方案1】:

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

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

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

>>> fst (1,1)
1
>>> fst (undefined,1)
undefined
>>> fst (1,undefined)
1
>>> fst undefined
undefined

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

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

【讨论】:

  • 非常感谢。因此,如果我做对了,在上述情况下,任何一个函数都不会在任一输入未定义的情况下运行,所以我可以说它们是相等的? (考虑到给定相同的有效输入,它们总是返回相同的结果)
  • 并非如此。这两个功能是平等的,但不是因为你所说的原因。如果f 没有检查它的输入,那么对于(undefined, undefined) 的输入,这两个函数都会返回True
猜你喜欢
  • 2012-01-10
  • 2013-12-02
  • 1970-01-01
  • 2016-09-18
  • 2015-08-24
  • 2020-02-12
  • 2015-08-21
相关资源
最近更新 更多