解析路径类型

问题描述

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

如果我使用通用名称

instance FromDhall (Path Rel Dir)

这不会对目录进行任何标准化。最初,我认为这会背负已定义的FromJSON实例,而该实例依次调用parseRelDir等,但事实并非如此,当我尝试手动实现此功能时,我意识到自己已经不知所措了。这是怎么做的?

解决方法

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

在这种情况下,由于Path在内部定义为:

newtype Path b t = Path FilePath

…,那么派生的FromDhall实例将期望Dhall值类似于这种类型:

{ _1 : Text }

…是具有1个匿名字段(即String / FilePath)的数据类型的派生Dhall类型。

这可能不是您想要的(如您所述),因此,如果您想要其他行为,则需要自己实现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