#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
пакете есть