У меня есть следующий DU, который состоит из других DU и / или записей. тип BiometricRules = | Возраст компаратора * AgeMeasure | Гликемия компаратора * Биометрические измерения | ...

3
Oanta William Richard 19 Янв 2021 в 17:54

1 ответ

Лучший ответ

Проблема

Fleece предоставляет кодеки Json, а не строковые кодеки, поэтому определение ToString и FromString не подходит, если они вам не нужны для других вещей.

Решение

Определите ToJson и OfJson для своих внутренних DU. Затем удалите все фрагменты |> string в теле JsonObjCodec.

Вот быстрый и грязный пример (я советую улучшить обработку ошибок) для Comparator:

    static member ToJson x = JString (string x)
    static member OfJson x =
        match x with
        | JString x -> Ok (Comparator.FromString x)
        | _ -> Error (Uncategorized "JString expected")

Альтернативное решение

Оставьте все ваши внутренние DU в таком виде, но добавьте недостающий раздел "parse" в свой JsonObjCodec:

    ...
    with
    static member JsonObjCodec =
        (fun (a, b) -> Age (Comparator.FromString a, AgeMeasure.FromString b)) <!> jreq "Age" (function Age (comp, ageMeasure) -> Some (comp |> string, ageMeasure |> string) | _ -> None)
    <|> ...

Это становится немного многословным, но выполнит свою работу.

< Сильный > Советы

  • Вместо использования оператора <|> для добавления кодеков вы можете использовать комбинатор jchoice, он будет лучше читать.

  • Если вам действительно нужны методы String / FromString, я бы предложил переименовать FromString в Parse или переименовать его в TryParse и вернуть тип параметра. Таким образом, вы можете воспользоваться функцией FSharpPlus tryParse.

  • Кроме того, если вы везде используете шаблон строки / синтаксического анализа, возможно, стоит создать комбинатор кодеков, который работает от преобразования в / из строк. Это непростая задача, но она может стоить умственных усилий.

  • Для отладки подобных вещей старайтесь не открывать пространство имен FSharpPlus, поскольку оно содержит общие определения операторов, таких как <|>, <!> и <*>, таким образом вы получите лучше компилировать сообщения об ошибках.

2
Gus 20 Янв 2021 в 08:22