1

我试图为该Path类型创建一个实例。https://hackage.haskell.org/package/path

如果我使用泛型。

instance FromDhall (Path Rel Dir)

这不会对目录进行任何规范化。我最初认为这会搭载定义的 FromJSON 实例,这些实例又会调用parseRelDir等,但事实并非如此,当我尝试手动实现它时,我意识到我完全不知所措。这样做的方法是什么?

4

1 回答 1

2

派生实例将使用Path数据类型的形状。即使Path构造函数没有暴露,它仍然提供一个Generic实例,这足以让FromDhall实例派生一些东西。

在这种情况下,sincePath内部定义为:

newtype Path b t = Path FilePath

…然后派生FromDhall实例将期望类似这种类型的 Dhall 值:

{ _1 : Text }

...这是具有 1 个匿名字段的数据类型的派生 Dhall 类型,即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
于 2020-10-01T03:49:24.933 回答