Nevertheless, the fact remains: these arguments were not enough for functional programming to become widespread. Therefore, we must conclude that the main drawback of functional programming is the flip side of its main virtue, namely that problems arise when (as is often the case) the system being designed must maintain some sort of state.
cake = cooled(removed_from_oven(added_to(30min, poured(greased(floured(pan)), stirred(chopped(walnuts),
alternating_mixed(buttermilk, whisked(flour, baking soda, salt),
mixed(bananas, beat_mixed(eggs, creamed_until(fluffy, butter, white sugar, brown sugar)))),
preheated(175C, oven))))))
cake = bake(cake_mixture, 30min, prepare(pan, (grease, flour)), preheated(175C, oven))
where cake_mixture =
creamed :until_fluffy âbutterâ âwhiteâ âsugarâ âbrown sugarâ
|> beat_mixed_with âeggsâ
|> mixed_with âbananasâ
|> mixed_with :alternating âbuttermilkâ âdry_goodsâ
|> mixed_with chopped âwalnutsâ
where dry_goods = whisked âflourâ âbaking sodaâ âsaltâ
ParseResult<V> VParser::parse_impl(ParseState state)
{
ParseResult<A> a = a_parser.parse(state);
if (ParseSuccess<A> * success = a.get_success())
return ParseSuccess<V>{{std::move(success->value)}, success->new_state};
ParseResult<B> b = b_parser.parse(state);
if (ParseSuccess<B> * success = b.get_success())
return ParseSuccess<V>{{std::move(success->value)}, success->new_state};
ParseResult<C> c = c_parser.parse(state);
if (ParseSuccess<C> * success = c.get_success())
return ParseSuccess<V>{{std::move(success->value)}, success->new_state};
ParseResult<D> d = d_parser.parse(state);
if (ParseSuccess<D> * success = d.get_success())
return ParseSuccess<V>{{std::move(success->value)}, success->new_state};
return select_parse_error(*a.get_error(), *b.get_error(), *c.get_error(), *d.get_error());
}
template<typename Variant, typename... Types>
ParseResult<Variant> parse_variant(ParseState state, Parser<Types> &... parsers)
{
boost::optional<ParseError> error;
template<typename T>
for (Parser<T> & parser : parsers)
{
ParseResult<T> result = parser.parse(state);
if (ParseSuccess<T> * success = result.get_success())
return ParseSuccess<Variant>{{std::move(success->value)}, success->new_state};
else
error = select_parse_error(error, *result.get_error());
}
return *error;
}
ParseResult<V> VParser::parse_impl(ParseState state)
{
return parse_variant<V>(state, a_parser, b_parser, c_parser, d_parser);
}
template<typename Variant, typename First>
ParseResult<Variant> parse_variant(ParseState state, Parser<First> & first_parser)
{
ParseResult<First> result = first_parser.parse(state);
if (ParseSuccess<First> * success = result.get_success())
return ParseSuccess<Variant>{{std::move(success->value)}, success->new_state};
else
return *result.get_error();
}
template<typename Variant, typename First, typename... More>
ParseResult<Variant> parse_variant(ParseState state, Parser<First> & first_parser,
Parser<More> &... more_parsers)
{
ParseResult<First> result = first_parser.parse(state);
if (ParseSuccess<First> * success = result.get_success())
return ParseSuccess<Variant>{{std::move(success->value)}, success->new_state};
else
{
ParseResult<Variant> more_result = parse_variant<Variant>(state, more_parsers...);
if (ParseSuccess<Variant> * more_success = more_result.get_success())
return std::move(*more_success);
else
return select_parse_error(*result.get_error(), *more_result.get_error());
}
}
ParseResult<V> VParser::parse_impl(ParseState state)
{
return parse_variant<V>(state, a_parser, b_parser, c_parser, d_parser);
}
Source: https://habr.com/ru/post/303312/
All Articles