我试图为该Path
类型创建一个实例。https://hackage.haskell.org/package/path
如果我使用泛型。
instance FromDhall (Path Rel Dir)
这不会对目录进行任何规范化。我最初认为这会搭载定义的 FromJSON 实例,这些实例又会调用parseRelDir
等,但事实并非如此,当我尝试手动实现它时,我意识到我完全不知所措。这样做的方法是什么?
我试图为该Path
类型创建一个实例。https://hackage.haskell.org/package/path
如果我使用泛型。
instance FromDhall (Path Rel Dir)
这不会对目录进行任何规范化。我最初认为这会搭载定义的 FromJSON 实例,这些实例又会调用parseRelDir
等,但事实并非如此,当我尝试手动实现它时,我意识到我完全不知所措。这样做的方法是什么?
派生实例将使用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