如何测试 lambda 演算?

Posted

技术标签:

【中文标题】如何测试 lambda 演算?【英文标题】:How to test lambda-calculus? 【发布时间】:2021-07-18 11:28:01 【问题描述】:

我在 C++ 中实现了 lambda 演算,但现在我不知道如何摆脱它。我想测试我的函数是否返回正确的东西,但我无法比较结果,因为它是一个函数。有谁知道如何测试我的代码?

    #include <functional>
    
    class function :
            public std::function<function (function)> 
        public: using type =
                std::function<function (function)>;
        public: using type::function;
    ;
    
    
    function True = [](function x) 
        return [&](function y) 
            return x;
        ;
    ;
    
    function False = [](function x) 
        return [&](function y) 
            return y;
        ;
    ;
    
    
    function If = [](function x) 
        return [&](function y) 
            return [&](function z) 
                return x(y)(z);
            ;
        ;
    ;
    
    
    function And = [](function x) 
        return [&](function y) 
            return x(y)(x);
        ;
    ;
    
    function Or = [](function x) 
        return [&](function y) 
            return x(x)(y);
        ;
    ;
    
    // ...
    
    
    int main()
    
        // ?
    

【问题讨论】:

function添加标签?使用“获取指向存储的指针”api?传递一个 null/not null 函数并使用 operator bool? 谢谢@Yakk-AdamNevraumont!我不想修改function 类,但是当我尝试调用返回的空函数时,我可以检查是否出现异常。当我写测试时,我会写下我的问题的答案。 你可以执行函数并断言结果 谢谢! @AlessandroTeruzzi std::function 并不意味着继承自,它没有virtual destructor 【参考方案1】:

我用下面的测试代码解决了我的问题。

#include <cassert>
#include <exception>

template <typename E, typename F>
bool throws(F f)
try 
    f();
    return false;

catch (E const &) 
    return true;



auto main() -> int

    function Null;
    assert(throws<std::bad_function_call>([&]  True(Null)(True)(True); ));
    assert(throws<std::bad_function_call>([&]  False(True)(Null)(True); ));

False 的测试有效,但True 的测试无效。第一个断言没有通过,我不知道为什么。当我通过值而不是通过引用 ([&amp;] -> [=]) 捕获 x 时,一切正常。

True 的新代码:

function True = [](function x) 
    return [=](function y) 
        return x;
    ;
;

有谁知道如果我通过引用捕获它为什么不起作用?

【讨论】:

我知道这个解决方案太复杂了。我正在重写它。【参考方案2】:

我的代码现在看起来像这样(我刚刚将所有 [&amp;] 替换为 [=] 并使用了私有继承):

class function :
        private std::function<function (function)> 
    public: using type =
            std::function<function (function)>;
    public: using type::function;
    public: using type::operator();
    public: using type::operator bool;
;


function True = [](function t) 
    return [=](function f) 
        return t;
    ;
;

function False = [](function t) 
    return [=](function f) 
        return f;
    ;
;


function If = [](function x) 
    return [=](function t) 
        return [=](function f) 
            return x(t)(f);
        ;
    ;
;


function And = [](function x) 
    return [=](function y) 
        return x(y)(x);
    ;
;

function Or = [](function x) 
    return [=](function y) 
        return x(x)(y);
    ;
;

测试看起来像这样:

auto main() -> int

    function Null;

    assert( True(True)(Null));
    assert(!True(Null)(True));

    assert( False(Null)(True));
    assert(!False(True)(Null));

    assert( If(True )(True)(Null));
    assert(!If(True )(Null)(True));
    assert( If(False)(Null)(True));
    assert(!If(False)(True)(Null));

    assert(And(False)(False) (Null)(True));
    assert(And(False)(True ) (Null)(True));
    assert(And(True )(False) (Null)(True));
    assert(And(True )(True ) (True)(Null));

    assert(Or(False)(False) (Null)(True));
    assert(Or(False)(True ) (True)(Null));
    assert(Or(True )(False) (True)(Null));
    assert(Or(True )(True ) (True)(Null));

【讨论】:

以上是关于如何测试 lambda 演算?的主要内容,如果未能解决你的问题,请参考以下文章

Lambda表达式

是否可以有效地评估 lambda 演算项?

Lambda 演算前导函数约简步骤

λ演算 (Lambda Calculus) 一 : 定义与函数式编程

是否有可能构建一个相对快速的无类型 lambda 演算机?

lambda演算感想之规则