data [a] = [] | a : [a]
list1 = [2,3,4]
list2 = 1 : 2 : list1
list3 = 0 : 0 : list1
1-2
\
2-3-4
/
0-0
do
x <- foo
y <- bar x
return $ baz y
x = foo();
if (x) {
y = bar();
if (y) {
return baz(y); } }
do
x <- lines str
y <- words x
return $ length y
for (x in lines(str))
for (y in words(x))
yield y.length();
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"]
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];
};
in.seekg (ios::end);
in.seekg (-1, ios::cur);
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);
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 = ['(', ')']
movieValue .: "id"
создает парсер, читающий id. Применённый к нему Movie <$>
создаёт парсер, который к id применит конструктор Movie, в итоге результатом такого парсера будет функция от одного недостающего аргумента.movieValue .: "title"
создаёт парсер, читающий title.<*>
, который создаст парсер, комбинирующий оба переданных ему парсера, применяя результат одного к результату другого. При этом так как оба парсера независимы, можно их выполнять в любом порядке. Но в данном случае слева направо. Проверить можно так:parseEither (\(Object v) -> (,) <$> v .: "a" <*> v .: "b") (object [])
Left "key \"a\" not present"
head <$> o .: "movies"
foo = add 2
, foo x
для некоторого x
всегда возвращает одно и то же значение, а также не производит никакого эффекта, наблюдаемого извне, и потому подпадает под определение чистой функции. Т.е. foo = add 2
идентичен функции foo x = 2 + x
, которая, очевидно, чистая. new char
выделит память только для одного символа, а у вас их много. То есть уже в следующей строке (cin >> array)
проезд по памяти. Если пишете в целях обучения и нельзя брать std::string
, то выделяйте с запасом, например new char[256];
Освобождать при этом память надо будет при помощи delete[] array
;cin >> array
делает это сам (пишет в конец array нулевой символ), а вы в своей функции нулевой символ не выставляете. Сделать это можно так:str[length_str] = '\0';
length_str
.delete []
#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;