• Что такое список в функциональных языках программирования?

    Отвечу за Haskell.
    Вот список:
    data [a] = [] | a : [a]
    Т.е. список либо пуст, либо имеет [ссылку на] [недовычисленную] голову и [ссылку на] [недовычисленный] другой список - хвост. Т.о. чтобы пробежаться по списку (без использования готовых функций), надо проверять, не является ли он пустым, если нет, работать с головой, а хвост обрабатывать рекурсивно.
    Список иммутабельный, т.е. ничего никуда вставить нельзя, однако списки могут "шарить" общий хвост, например:
    list1 = [2,3,4]
    list2 = 1 : 2 : list1
    list3 = 0 : 0 : list1

    В памяти будет (после форсирования, рассмотрение ленивости я опускаю) как-то так:
    1-2
       \
        2-3-4
       /
    0-0
    Ответ написан
    Комментировать
  • Зачем нужны монады?

    То, что вы описали - частный случай.
    Вот несколько частных случаев (хаскель vs псевдокод).
    Обратите внимание, что на Хаскеле код линейный
    То, что сделано монадами, в других языках нередко встроено. Удобство невстроенного решения в том, что есть немало функций, которые работают с любыми монадами (mapM, filterM, ...), применить которые к встроенным в язык вещам может быть проблематично.

    1. nullable
    do
        x <- foo
        y <- bar x
        return $ baz y

    вместо
    x = foo();
    if (x) {
        y = bar();
        if (y) {
            return baz(y); } }


    2. списки
    do
        x <- lines str
        y <- words x
        return $ length y

    вместо
    for (x in lines(str))
        for (y in words(x))
            yield y.length();


    3. continuation
    do
        h1 <- ContT $ withFile "1.txt" ReadMode
        h2 <- ContT $ withFile "2.txt" WriteMode
        liftIO $ ...use handles...

    вместо
    using (h1 = File.Open("1.txt", File.Mode.Read)) {
        using (h2 = File.Open("2.txt", File.Mode.Write)) {
            ...use files... }}


    Причем можно, например, и так:
    do
        -- сразу список файлов открываем
        hs <- mapM (\name -> ContT (withFile name ReadMode))
            ["1.txt", "2.txt", "3.txt", "4.txt"]

    А как сделать так с using'ами?
    Ответ написан
    Комментировать
  • Сколько чисел, не превосходящих 240, которые не делятся ни на 2, ни на 3, ни на 5?

    Посчитать те, которые делятся хотя бы на одно. При этом надо учитывать, что некоторые числа будут посчитаны несколько раз. Надо воспользоваться формулой включений-исключений.
    Итого делящихся хотя бы на одно из этих чисел:
    240/2 + 240/3 + 240/5 - 240/(2*3) - 240/(2*5) - 240/(3*5) + 240/(2*3*5) = 176
    Значит, неделящихся 240 - 176 = 64

    Проверяем:
    ghci> length $ filter (\x -> 0 `notElem` [x `mod` 2, x `mod` 3, x `mod` 5]) [1..240]
    64
    Ответ написан
    Комментировать
  • Что не так с кодом?

    Нет реализации соответствующих методов.
    Допишите их, например, так:
    class car {
     public :
         void Start () { ... }
         void Accelerate() { ... }
         void Brake() { ... }
         void setYear(int year) { this->year = year; }
         int getYear() { return year; }
    
     private :
        int year;
        char model [255];
     };
    Ответ написан
    1 комментарий
  • Почему не работает код с++?

    in.seekg (ios::end);
    Чтобы прочесть последний символ, стоять надо не в конце, а на один символ раньше. В вашем случае читать уже нечего.

    in.seekg (-1, ios::cur);
    Этим вы только отшагнёте обратно на один символ, который только что прочли.

    Если файлы невелики, проще будет прочесть его весь прочесть в std::vector, а потом просто скопировать в выходной файл:

    std::vector<char> cts;
    in.seekg(0, in.end);
    cts.resize(in.tellg());
    in.seekg(0, in.beg);
    
    in.read(&ctr[0], ctr.size());
    
    std::ostream_iterator<char> out_it(out);
    std::copy(cts.rbegin(), cts.rend(), out);
    Ответ написан
    5 комментариев
  • Как рекурсивно распарсить скобки?

    Во-первых, заменим splitOn " " на words, который съест все пробелы. Далее, concat $ map ... - это то же, что и concatMap .... Рассмотрим sepBr. Он берёт строку без пробелов и делит её на куски, если там есть операторы, числа или скобки. Если строка уже пустая, результат - пустой список. Если строка непустая, то возможны варианты. Если первый её символ - какая-то скобка, отделяем эту скобку, а остальное делим опять при помощи sepBr. Иначе делаем так: разделим строку, чтобы сначала шли только цифры: span isDigit и посмотрим, что получилось. Если цифры есть - отделяем их, а остальное опять делим sepBr. Если цифр нет, то просто отделяем первый символ. Вот, что получилось:
    sep ∷ String → [String]
    sep = concatMap sepBr . words where
    	sepBr ∷ String → [String]
    	sepBr "" = [] -- нечего делить
    	sepBr s'@(x:xs)
    		| x `elem` "()" = [x] : sepBr xs -- скобка
    		| otherwise = case span isDigit s' of -- возьмём цифры
    			("", t:tl) → [t] : sepBr tl -- нет цифр, берём первый символ остатка
    			(n, tl) → n : sepBr tl -- есть цифры, их отдельно


    По поводу вашего второго варианта.
    if word == [] then [] else head word - т.е. a либо пустой список, либо символ, типы не совпадают. Но в вашем случае word не может быть пустым, ведь выше уже был паттерн sepBr "", так что можно просто оставить a = head word
    Далее, что такое ab? Это [a] ++ b, т.е. [head word] ++ init (tail word), т.е. это то же, что и просто init word. Аналогично bc = tail word. Вместо того, чтобы брать отдельно head и отдельно tail, можно воспользоваться паттерн-матчингом и записать (a : bc) = word.
    С учётом этого ваш вариант переписывается в
    sep2 ∷ String → [String]
    sep2 = concatMap sepBr . words where
    	sepBr ∷ String → [String]
    	sepBr ""  = []
    	sepBr " " = []
    	sepBr word
    		| a `elem` brackets = [[a]] ++ sepBr bc
    		| c `elem` brackets = sepBr ab ++ [[c]]
    		| otherwise = ([a : bc])
    		where
    			(a : bc) = word
    			c = last word
    			ab = init word
    			brackets = ['(', ')']

    И он вполне работает.
    Ответ написан
    1 комментарий
  • Как порядок вычисления выражений в этом коде?

    movieValue .: "id" создает парсер, читающий id. Применённый к нему Movie <$> создаёт парсер, который к id применит конструктор Movie, в итоге результатом такого парсера будет функция от одного недостающего аргумента.
    Также movieValue .: "title" создаёт парсер, читающий title.
    Если б это были просто функция и значение, можно было бы одно к другому применить, в нашем случае используют <*>, который создаст парсер, комбинирующий оба переданных ему парсера, применяя результат одного к результату другого. При этом так как оба парсера независимы, можно их выполнять в любом порядке. Но в данном случае слева направо. Проверить можно так:
    parseEither (\(Object v) -> (,) <$> v .: "a" <*> v .: "b") (object [])

    Ответ:
    Left "key \"a\" not present"
    Если бы он сначала вычислял правый аргумент, ошибка была бы другая - не найден b.

    А что вы имеете в виду под порядком вычисления?
    head <$> o .: "movies"
    Хаскель ленивый язык, пока не понадобится, не вычисляет. В этой строке вы, считай, thunk создали, который, когда его дёрнут, начнёт что-то там вычислять. В этом примере, когда дёрнут, начнёт вычислять, а не фейлится ли парсер, для чего придётся убедиться, что не фейлятся входящие в него парсеры. Порядок может быть любой, но автор библиотеки скорее всего сделал порядок естественным.
    Ответ написан
    7 комментариев
  • Как работает перегрузка с $null?

    https://msdn.microsoft.com/en-us/library/system.ne...(v=vs.110).aspx
    If you pass an empty string as the host name, this method retrieves the standard host name for the local computer.
    Ответ написан
  • Поясните про замыкания в ФП?

    Чистая. Рассмотрим foo = add 2, foo x для некоторого x всегда возвращает одно и то же значение, а также не производит никакого эффекта, наблюдаемого извне, и потому подпадает под определение чистой функции. Т.е. foo = add 2 идентичен функции foo x = 2 + x, которая, очевидно, чистая.
    Ответ написан
    2 комментария
  • Существует ли возможность ярко выделить строку в Sublimetext 3?

    Как верно заметили, чтобы было на миникарте, надо, чтобы было видно и в самом редакторе.
    Вариантов мне видится два:
    1. Подправить соответствующий tmLanguage, добавив туда правило для такого особенного комментария и выставив ему нужный контрастный цвет
    2. Написать (или поискать) плагин, который делал бы аналогичное без правки описания синтаксиса языка: находил бы нужные комментарии и навешивал на них регионы (API функции add_regions). Единожды навешенный, такой регион сам смещается куда надо при редактировании и подсвечивает ту же область. Так что можно сделать и более гибко: по сочетанию клавиш вставлять такой комментарий и сразу его подсвечивать, тогда не придётся вообще ничего парсить.

    Если не найдете подобного плагина и захотите реализовать, напишите, скооперируемся.
    Ответ написан
    6 комментариев
  • Лишние символы в c++, откуда?

    Во-первых, new char выделит память только для одного символа, а у вас их много. То есть уже в следующей строке (cin >> array) проезд по памяти. Если пишете в целях обучения и нельзя брать std::string, то выделяйте с запасом, например new char[256]; Освобождать при этом память надо будет при помощи delete[] array;
    Во-вторых, конец строки определяется по нулевому символу на конце. cin >> array делает это сам (пишет в конец array нулевой символ), а вы в своей функции нулевой символ не выставляете. Сделать это можно так:
    str[length_str] = '\0';
    Но надо иметь в виду, что памяти надо выделить [хотя бы] на 1 больше, чем length_str.

    Итого:
    1. Вам надо в обоих случаях память выделять под массив. В первом случае можно под 256 элементов. В идеале при этом читать не при помощи cin, а другими функциями, дабы избежать переполнения на случай, если введут строку более длинную.
    2. В reverse надо выставлять терминирующий нуль и исправить длину массива. Возможно вообще разворачивать строку по месту, т.е. менять местами буквы, а не создавать новую строку (в этом случае не надо ни память выделять, ни трогать терминирующий нуль, он останется на месте).
    3. Вам надо удалять выделенную память по окончании использования при помощи delete []
    Ответ написан
    2 комментария
  • Как распарсить сложную строку на Swift?

    swift не знаю, но с учётом вашего "и потом" предлагаю:
    split(incomeText) {$0 == "{" || $0 == "}"}
    Ответ написан
    Комментировать
  • Почему в Sublime text 3 возникает ошибка error tryning to parse settings?

    Впечатление такое, будто кодировка UTF-16 с BOM. У себя проверил - да. Если выбрать "Save with encoding" и выбрать какой-нибудь UTF с BOM - не читает. Пересохраните в просто UTF-8: "Save with encoding - UTF-8"
    Ответ написан
    Комментировать
  • Как записать в map?

    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <map>
    
    std::string str[3] = { "foo bar", "baz quux", "x y" };
    std::map<std::string, std::string> d;
    
    for (auto const & s : str)
    {
    	auto it = s.find(' ');
    	if (it != std::string::npos)
    		d[s.substr(0, it)] = s.substr(it + 1);
    }
    
    for (auto const & kv : d)
    	std::cout << kv.first << " = " << kv.second << std::endl;
    Ответ написан
    Комментировать