LanguageExt Свернуть список обоих - PullRequest
1 голос
/ 15 октября 2019

У меня есть функция, которая выполняет набор запросов, каждый из которых возвращает Either<Error, Result>. Я собираю их в List<>. Я хочу сложить эти отдельные возвращаемые значения вместе, чтобы общий возвращаемый результат составил Either<Error, List<Result>>. Я получил это далеко;

class Error
{
    string Message { get; set; }
    List<Error> ChildErrors { get; set; }
}

class Result
{
}

Either<Error, List<Result>> GetResults(List<string> queries)
{
    var internalResults = new List<Either<Error, Result>>();

    foreach (string query in queries)
    {
        internalResults.Add(GetResultForQuery(query));
    }

    var initialState = (new List<Error>(), new List<Result>());

    (List<Error> errors, List<Result> events) =
        internalResults.Fold(initialState, (state, item) =>
    {
        (List<Error> err, List<Result> res) = state;
        item.Right(i => res.Add(i)).Left(e => err.Add(e));
        return (err, res);
    });

    if (errors.Count > 0)
    {
        var groupedError = new Error {
            Message = "One or more problems encountered",
            ChildErrors = errors
        };

        return Left<Error, List<Result>>(groupedError);
    }

    return Right<Error, List<Result>>(events);
}

Я считаю, что это должно работать, но это не особенно элегантно. Должен быть лучший способ сделать это (то есть более монадический). Любые подсказки?

1 Ответ

1 голос
/ 15 октября 2019

Вам следует заменить System.Collections.Generic.List на один из типов данных LanguageExt, например, Seq или Lst или Arr ...

Я использовал Seq здесь для иллюстрации. Вы также можете конвертировать IEnumerable в Seq, используя расширение ToSeq().

Тогда вы можете использовать Sequence как здесь без каких-либо хлопот:


class Error
{
    string Message { get; set; }
    Seq<Error> ChildErrors { get; set; }
}

class Result
{
}

private static Either<Error, Result> GetResultForQuery(string query) =>
    throw new NotImplementedException();

Either<Error, Seq<Result>> GetResults(Seq<string> queries)
{
    Seq<Either<Error, Result>> internalResults = queries.Map(GetResultForQuery);

    return internalResults.Sequence();
}

Either<Error, Seq<Result>> GetResults2(Seq<string> queries) =>
    queries.Map(GetResultForQuery).Sequence();

GetResults2 isпросто короткая версия GetResults.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...