ніколи не працював з wolfram matemathica.
свого часу, коли я займався чисельними розрахунками, це була теж лінійна алгебра, множення матриць, але це все було на с++. Єдина проблема яку я мав: це було ще під дос і там RAND_MAX був 65536, і отже випадкові числа 1.0*rand()/RAND_MAX були гранульовані по 1/65536. це породжувало цікаві ефекти, які зникли коли код скомпілювали під лінукс в якому RAND_MAX 32 бітне число. більше нічого про лінійну алгебру я вам сказати не можу:)
>Тупі людишки!
це написали ви, а не я. не бачу конструктивної критики.
Пишемо, скажемо, функцію для рахування детермінанта через розклад Лапласа, і сподіваємося що скажемо ліниво підставивши його в формулу Крамера все красиво поскорочує компіляторможете продемонструвати? а краще напишіть про це статтю. мені буде цікаво почитати, обіцяю:)
якщо вважати, що node_left або node_right ніколи не буде рівними нулю, і root кладеться в стек перед викликом функції, то
... stack.push(root); stum_iter2(0,stack); ... int tsum_iter2(int sum, std::stack<tree *> stack) { while (!stack.empty()) { tree *current = stack.top(); stack.pop(); if (current->is_leaf) { sum += current->leaf_value; continue; } stack.push(current->node_right); stack.push(current->node_left); } return sum; }далі переходимо tail call optimized версію.
int tsum_acc2(int sum, std::stack<tree *> stack) { if (stack.empty()) return sum; tree *current = stack.top(); stack.pop(); if (current->is_leaf) { sum += current->leaf_value; return tsum_acc2(sum, stack); } stack.push(current->node_right); stack.push(current->node_left); return tsum_acc2(sum, stack); }що на хаскелі очевидно виглядає якось так
tsum_acc2 acc [] = acc tsum_acc2 acc ((Leaf x):xs) = tsum_acc2 (acc+x) xs tsum_acc2 acc ((Node a b):xs) = tsum_acc2 acc (a:b:xs)схоже, що ваша tsum_acc2 визначається так
tsum_acc2 a xs = a + reduce xsперевіримо
tsum_acc2 a [] = a + reduce [] = a tsum_acc2 a ((Leaf x):xs) = a + tsum (Leaf x) + reduce xs = a + x + reduce xs = tsum_acc2 (a+x) xs tsum_acc2 a ((Node x y):xs) = a + tsum (Node x y) + reduce xs = a + tsum x + tsum y + redure xs = a + tsum x + reduce (y:xs) = a + reduce (x:y:xs) = tsum_acc2 acc (x:y:xs)вірно.
tsum_acc2 a [] = a + reduce [] tsum_acc2 a [x] = a + tsum x tsum_acc2 a (x:xs) = a + tsum x + reduce xsз чого слідує
tsum_acc2 0 [x] = tsum x tsum x = tsum_acc2 0 [x]або
tsum_acc2 0 [x] = tsum_acc 0 [] xщо є _математичним_ доказом, що ви написали те саме, що і я. але маю зазначити, що ваш код виконує більше stack.push(). можете це перевірити.
всякі різні процеси (і бізнес логіку також) часто малюють квадратиками і стрілочками. їх дуже зручно моделювати стрілками (ті що Arrows у хаскелі). хоча код Arrows дійсно ніхто не любить.
я не виправдовую, але це не расизм, бо «яка-не-підтримує-курс-ворожби-з-Росією» не раса, а просто тупість. до речі в самій цій фразі вже закладено маніпуляцію, бо всі хто не «яка-не-підтримує-курс-ворожби-з-Росією» нібито за ворожбу з росією. тобто S M дуже схожий на кацаського бота.
ну блін. розмір стека ядра лінукс 8Kb. думаю ви скотилися у сарказм, тому що не можете написати нічого конструктивного. краще напишіть статтю про балансування дерев і метод Моріса. Мені буде цікаво почитати, обіцяю.
>що таке монада
у рівнянні F = ma сила і прискорення векторні величини. можна і без векторів, але тоді буде система рівнянь. А що таке вектор? це деяка абстрактна штука, якою моделюють дещо, що має не тільки величину , але і напрямок.
так от програма на хаскелі це і не програма, а рівняння, яке моделює поведінку комп’ютера під час виконання програми. і для моделювання ефектів, які виникають під час виконання програми використовують абстрактне математичне поняття, монаду, про властивості якої написано вже де тільки можна. причому не обов’язково використовувати монади. наприклад RR парсер json може бути аплікативним, йому не обов’язково бути монадою. а може бути і не аплікативний, але буде така шляпа, що важко буде в чому розібратися.
>банально заміна класу
приходьте до нас, хаскелістів. у нас є і монади і класи:)
>instance Foldable
хід конем звичайно, але тоді б і статі б не було. схоже ви не зрозуміли головну ідею статі
Дякую, але 1. мені здається балансування дерева теж рекурсивне; 2. не обов’язково брати саме std::vector, та і взагалі тут задача про використати heap замість стеку, а як той heap використаний то вже інша справа.
Нагадую, що це задача демонстративна. Є інші подібні задачі не обов’язково з деревами
там в кінці є
тим часом літр молока в селі можна купити за 9 грн.
як я можу згадати те, чого не знаю? :)
you guys know mascot of c++?
кохання це...
... обирати мову програмування по маскоту
в 2015 поклацав касету на батьківскому зеніті з цікавості. настільки був вражений, що купив canon 50e і здоровенну мамію супер 23. з тих пір з ними і ходжу. але це не дешевше ніж цифра, так.
а так?
function is_correct(rectangleSize, fitSize) { return !rectangleSize?.width || !rectangleSize?.height || !fitSize } function fitRectangleToSquare2(rectangleSize, fitSize) { if (!is_correct(rectangleSize, fitSize)) return null let { width, height } = rectangleSize, ratio = (width > height)? fitSize/width : fitSize/height, newWidth = Math.ceil(width * ratio), newHeight = Math.ceil(height * ratio), result = {width: newWidth, height: newHeight} ; return result }
цей метод форматування має прямий зв’язок з фп. уявіть у вас є функція для чисел Фібоначчі
f 0 = 0 f 1 = 1 f x = f (x-1) + f (x-2)перші два випадки це частинні випадки. якщо писати це на спп то буде якось так
int f(int x) { if (x == 0) return 0; if (x == 1) return 1; return f(x-1) + f (x-2); }на мій погляд ідеальний стиль, використовую усюди де можу. може навіть так писати.
int f(int); int result_for_case0() { return 0; } int result_for_case1() { return 1; } int result_for_others(int x) { return f(x-1) + f(x-2); } int f(int x) { switch (x) { case 0: return result_for_case0(); case 1: return result_for_case1(); default: return result_for_others(x); } }це звичайно схематично, але дозволяє не писати коменти взагалі.
тут очевидно автор хотів зробити відкладений апдейт, прикрутити асинхроність чи щось таке, але відклав цю роботу на майбутнє. написав синхрону реалізацію, аби працюівало, а майбутнє поки що так і не наступило:)
Проблема пояснення, що таке монада полягає в тому, що математичні теорії це науки про абстракції. арифметика, числа — модель кількості, абстракція від кількості чогось. геометрія — точки і прямі, абстракції форми. а от теорія категорія — це узагальнення різних математичних розділів, і виходить, що монада — абстракція над абстракціями. і тому пояснити що таке монада можна лише, на основі визначення, (оті самі ендофунктори) або на прикладах. Обидва методи, як виявилося, працюють дуже погано.
щодо абстракції в доменній області я з вами абсолютно погоджуюсь. правильний шлях в тому, щоб визначити абстракції і їх властивості. і якщо ці властивості співпадають з якимось типом, то вам пощастило — ви маєте купу функцій, які можуть стати у нагоді.
плюс монад в тому, що для них є трансформери, які дозволяють їх комбінувати. І тут же існують речі які не є монадами, але трансформер для них можна написати, наприклад індексні монади, що дуже зручно з практичних міркувань.