Как работает эта функция Fold Tree в Haskell

& lt; just for fun & gt;

  • , позволяющий произвольное количество аргументов
  • , к счастью, sizeof (std :: wstring) является кратным sizeof (int)
  • проверен на w2k3 sp2 32bit + visual c ++ 2010

#include <stdarg.h>
#include <string>
#include <vector>
#include <iostream>

#define N 6 // test argument count

void foo(int n, ...);

int main(int, char*[])
{
    std::vector strings;
    std::wstring s(L"a");
    int i(0);

    // create unique strings...
    for (; i != N; ++i)
    {
        strings.push_back(s);
        ++s.front();
    }

    int n_stack_strings(N*sizeof(std::wstring)),    // space needed for strings
        n_stack(sizeof(int)+n_stack_strings);   // overall stack space...needed for cleanup

    __asm sub esp, n_stack_strings  ; reserve stack space

    std::wstring* p_stack(0);

    __asm mov p_stack, esp  ; get stack pointer

    std::wstring* p(p_stack);
    std::vector<std::wstring>::iterator string(strings.begin());

    // copy to stack
    for (; string != strings.end(); ++string, ++p)
        new (p) std::wstring(*string);
    __asm push N    ; argument count...arguments right to left (__cdecl)
    __asm call foo
    // cleanup
    for (p = p_stack; p != p_stack+N; ++p)
        p->~basic_string();
    __asm add esp, n_stack  ; caller has to cleanup the stack (__cdecl)
    return 0;
}

void foo(int n, ...)
{
    int i(0);
    va_list marker;

    va_start(marker, n);
    for (; i != n; ++i)
        std::wcout << va_arg(marker, std::wstring) << std::endl;
    va_end(marker);
}

& lt; / just for fun & gt;

1
задан Will Ness 12 March 2019 в 09:29
поделиться

1 ответ

Чтобы понять результат foldTree f g tree, вы можете использовать эту технику:

  • Запишите значение tree, используя конструкторы, например, в вашем примере мы имеем (Node (Node (Leaf 1) (Leaf 2)) (Leaf 4)).
  • Синтаксически заменить Leaf на f и Node на g. Для предыдущего примера мы получаем (g (g (f 1) (f 2)) (f 4)).
  • Используйте определения функций f и g для вычисления результата последнего выражения. Для примера, мы получаем ((+) ((+) ((*2) 1) ((*2) 2)) ((*2) 4)), который является ((+) ((+) (1*2) (2*2)) (4*2)), который является ((1*2) + (2*2)) + (4*2), который является (2+4)+8 = 14.

Обратите внимание, как мы заменяем Leaf унарный конструктор на f, унарную функцию, и Node, двоичный конструктор с g, двоичную функцию. Таким образом, у нас всегда есть правильное количество аргументов для наших функций. В общем, типы будут соответствовать просто отлично.

0
ответ дан chi 12 March 2019 в 09:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: