Тип пути синтаксического анализа

#dhall

#dhall

Вопрос:

Я пытался создать экземпляр для этого Path типа. https://hackage.haskell.org/package/path

Если я использую общий.

 instance FromDhall (Path Rel Dir)
  

Это не приводит к какой-либо нормализации каталогов. Изначально я предполагал, что это приведет к возврату определенных экземпляров FromJSON, которые, в свою очередь, вызывают parseRelDir etc, но это не так, и когда я попытался реализовать это вручную, я понял, что я совсем запутался. Как это можно сделать?

Ответ №1:

Производный экземпляр будет использовать форму Path типа данных. Даже если Path конструктор не открыт, он все равно предоставляет Generic экземпляр, которого достаточно, чтобы FromDhall экземпляр мог что-то получить.

В этом случае, поскольку Path внутренне определяется как:

 newtype Path b t = Path FilePath
  

… тогда производный FromDhall экземпляр будет ожидать значение Dhall примерно такого типа:

 { _1 : Text }
  

… который является производным типом Dhall для типа данных с 1 анонимным полем, которое является String / FilePath .

Вероятно, это не то, что вы хотели (как вы отметили), поэтому, если вы хотите другого поведения, вам нужно будет реализовать FromDhall экземпляр самостоятельно.

Итак, что вы, вероятно, захотите написать, это что-то вроде:

 instance FromDhall (Path Rel Dir) where
    -- Our `Decoder` will be similar to the `filePathDecoder`,
    -- except with a different `extract` function
    autoWith options =
        Decoder
            { extract = extractPath
            , expected = expectedPath
            }
      where
        filePathDecoder :: Decoder FilePath
        filePathDecoder = autoWith options

        -- To extract a `Path`, first extract a `FilePath`
        -- and attempt to parse it into a `Path`
        extractPath expression =
          case extract filePathDecoder expression of
              Success filepath ->
                  case Path.parseRelDir filePath of
                      Left exception ->
                          Dhall.extractError (Text.pack (show exception))
                      Right path ->
                          Success path
              Failure e -> Failure e

        -- The expected Dhall type for a `Path` is the same
        -- as for a `FilePath`
        expectedPath = expected filePathDecoder
  

Комментарии:

1. Спасибо за исчерпывающий пример. Как он автоматически преобразует ограничение MonadThrow в Either?

2. @locallycompact: instance (e ~ SomeException) => MonadThrow (Either e) в exceptions пакете есть