Использование замены / возврата по умолчанию при обработке «сбоя» при использовании LanguageExt? - PullRequest
2 голосов
/ 29 октября 2019

У меня есть функция, которая возвращает либо. Находя левый возврат, я хотел бы заменить какой-то объект по умолчанию и обработать его. Каков подходящий шаблон, использующий Language Ext, для этого?

Ниже приведена модель для этого - myfunc возвращает Either, и если он возвращает TestFail, я бы хотел заменить его пустой строкой [] иобработать это. Следующее выглядит ужасно - оно проверяет нулевое значение и полагается на неявное преобразование Either в EitherData с помощью let:

using System.Linq;
using LanguageExt;

// Call with true or false to explore each branch ...
public void Sandbox(bool succeed)
{
    Either<TestFail, string[]> myFunc(bool shouldSucceed)
    {
        if (shouldSucceed)
        {
            return new[] {"hello", "world"};
        }
        return new TestFail("i was doomed.");
    }

    var x =
        from response in myFunc(succeed)
        let failures = response.Left
        let strings = response.Right
        from str in failures != null
            ? new string[0] // if myFunc failed, just process nothing/null obj
            : strings
        select "x" + str;
}

с простым классом TestFail:

public class TestFail
{
    public string Reason { get; }
    public TestFail(string reason)
    {
        Reason = reason;
    }
}

Две вещи: 1. неявное приведение одиночного Either к IEnumerable выставляет Left и Right напрямую без всякой безопасности Either - это намеренно. 2. как лучше обработать сбой в myfunc?

Запах в том, что меня не интересует Either from myfunc. Если у меня есть контроль над этим, я, вероятно, должен просто поглотить проблемы в нем и убедиться, что я возвращаю значение по умолчанию при ошибке. Однако, если я не контролирую это - что делать?

Ответы [ 2 ]

2 голосов
/ 05 ноября 2019

Существует множество вспомогательных функций для монад в LanguageExt, в этом случае вы пытаетесь указать значение по умолчанию, если в левом состоянии элемента Either иначе вернуть значение справа. IfLeft для этой конкретной цели:

var res = myFunc(succeed).IfLeft(new string[0]);
0 голосов
/ 29 октября 2019

Насколько мне известно, вы не можете иметь тип возвращаемого значения переменной. Типы обязательны для того, чтобы компилятор знал, какую функцию даже вызывать, или если контекст, который вы используете, имеет смысл.

Также, как правило, вы не должны бороться с проверками типов. Они твой лучший друг, а не враг. А отсутствие их и агрессивное неявное преобразование - вот что приводит примеры PHP и JavaScript из этого комикса .

Большинство решений обходятся вокруг этого, имея несколько возвращаемых значений, каждое из которых может иметь разныетип:

1 Создайте структуру, кортеж или класс , которые могут иметь как успех, так и результат, используйте его в качестве возвращаемого типа. Но ты вроде уже сделал это. Проверьте значения успеха, прежде чем использовать возвращаемое значение. Дополнительные параметры превратят результат в свойство, которое вызовет исключение, если sucess имеет значение false. См. Класс Task и BackgroundWorkerCompletedEventArgs.Result для примеров этого.

2 Создайте поверхностную иерархию классов . Что-то вроде

abstract class BaseReturnValue { }
class FailureValue : BaseReturnValue { }
class SuccessValue : BaseReturnValue { string value; }

Функция будет возвращать тип BaseReturnValue. Но поскольку он является абстрактным, вы можете использовать только экземпляры FailureValue или SuccessValue в коде. Остальные - проверки.

3 Выходные параметры. Out позволяет получить более одного возвращаемого значения без необходимости написания класса. Все варианты TryParse () использует его для возврата логического значения, указывающего на успешность, и в то же время дает вам также проанализированное целое число.

...