我试图为Path
类型创建一个实例。 https://hackage.haskell.org/package/path
如果我使用通用名称。
instance FromDhall (Path Rel Dir)
这不会对目录进行任何标准化。最初,我认为这会背负已定义的FromJSON实例,而该实例依次调用parseRelDir
等,但事实并非如此,当我尝试手动实现此功能时,我意识到自己已经不知所措了。这是怎么做的?
答案 0 :(得分:2)
派生的实例将使用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