Skip to content

Commit cbb0e93

Browse files
committed
Alpha-normalize expressions in toDirectoryTree
1 parent ac1f611 commit cbb0e93

File tree

1 file changed

+17
-19
lines changed

1 file changed

+17
-19
lines changed

dhall/src/Dhall/DirectoryTree.hs

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
{-# LANGUAGE LambdaCase #-}
66
{-# LANGUAGE OverloadedLists #-}
77
{-# LANGUAGE OverloadedStrings #-}
8+
{-# LANGUAGE PatternSynonyms #-}
89
{-# LANGUAGE RecordWildCards #-}
910
{-# LANGUAGE StandaloneDeriving #-}
1011
{-# LANGUAGE TupleSections #-}
@@ -45,7 +46,6 @@ import Dhall.Syntax
4546
, Const (..)
4647
, Expr (..)
4748
, FieldSelection (..)
48-
, FunctionBinding (..)
4949
, RecordField (..)
5050
, Var (..)
5151
)
@@ -173,15 +173,16 @@ import qualified System.PosixCompat.User as Posix
173173
internally.
174174
175175
__NOTE__: This utility does not take care of type-checking and normalizing
176-
the provided expression. This will raise a `FilesystemError` exception upon
177-
encountering an expression that cannot be converted as-is.
176+
the provided expression. This will raise a `FilesystemError` exception or a
177+
`DhallErrors` exception upon encountering an expression that cannot be
178+
converted as-is.
178179
-}
179180
toDirectoryTree
180181
:: Bool -- ^ Whether to allow path separators in file names or not
181182
-> FilePath
182183
-> Expr Void Void
183184
-> IO ()
184-
toDirectoryTree allowSeparators path expression = case expression of
185+
toDirectoryTree allowSeparators path expression = case Core.alphaNormalize expression of
185186
RecordLit keyValues ->
186187
Map.unorderedTraverseWithKey_ process $ recordFieldValue <$> keyValues
187188

@@ -208,7 +209,7 @@ toDirectoryTree allowSeparators path expression = case expression of
208209
-- If this pattern matches we assume the user wants to use the fixpoint
209210
-- approach, hence we typecheck it and output error messages like we would
210211
-- do for every other Dhall program.
211-
Lam _ (functionBindingVariable -> r) (Lam _ (functionBindingVariable -> make) body) -> do
212+
Lam _ _ (Lam _ _ body) -> do
212213
let body' = Core.renote body
213214
let expression' = Core.renote expression
214215

@@ -218,9 +219,7 @@ toDirectoryTree allowSeparators path expression = case expression of
218219

219220
_ <- Core.throws $ TypeCheck.typeOf $ Annot expression' expected'
220221

221-
let expr = rename r "result" $ rename make "make" body'
222-
223-
entries <- case Decode.extract decoder expr of
222+
entries <- case Decode.extract decoder body' of
224223
Success x -> return x
225224
Failure e -> Exception.throwIO e
226225

@@ -229,11 +228,6 @@ toDirectoryTree allowSeparators path expression = case expression of
229228
decoder :: Decoder (Seq FilesystemEntry)
230229
decoder = Decode.auto
231230

232-
rename :: Text -> Text -> Expr s a -> Expr s a
233-
rename a b expr
234-
| a /= b = Core.subst (V a 0) (Var (V b 0)) (Core.shift 1 (V b 0) expr)
235-
| otherwise = expr
236-
237231
_ ->
238232
die
239233
where
@@ -261,8 +255,8 @@ toDirectoryTree allowSeparators path expression = case expression of
261255

262256
-- | The type of a fixpoint directory tree expression.
263257
directoryTreeType :: Expector (Expr Src Void)
264-
directoryTreeType = Pi Nothing "result" (Const Type)
265-
<$> (Pi Nothing "make" <$> makeType <*> pure (App List (Var (V "result" 0))))
258+
directoryTreeType = Pi Nothing "tree" (Const Type)
259+
<$> (Pi Nothing "make" <$> makeType <*> pure (App List (Var (V "tree" 0))))
266260

267261
-- | The type of make part of a fixpoint directory tree expression.
268262
makeType :: Expector (Expr Src Void)
@@ -273,7 +267,11 @@ makeType = Record . Map.fromList <$> sequenceA
273267
where
274268
makeConstructor :: Text -> Decoder b -> Expector (Text, RecordField Src Void)
275269
makeConstructor name dec = (name,) . Core.makeRecordField
276-
<$> (Pi Nothing "_" <$> expected dec <*> pure (Var (V "result" 0)))
270+
<$> (Pi Nothing "_" <$> expected dec <*> pure (Var (V "tree" 0)))
271+
272+
-- | Utility pattern synonym to match on filesystem entry constructors
273+
pattern Make :: Text -> Expr s a -> Expr s a
274+
pattern Make label entry <- App (Field (Var (V "_" 0)) (fieldSelectionLabel -> label)) entry
277275

278276
type DirectoryEntry = Entry (Seq FilesystemEntry)
279277

@@ -287,11 +285,11 @@ data FilesystemEntry
287285

288286
instance FromDhall FilesystemEntry where
289287
autoWith normalizer = Decoder
290-
{ expected = pure $ Var (V "result" 0)
288+
{ expected = pure $ Var (V "tree" 0)
291289
, extract = \case
292-
App (Field (Var (V "make" 0)) (fieldSelectionLabel -> "directory")) entry ->
290+
Make "directory" entry ->
293291
DirectoryEntry <$> extract (autoWith normalizer) entry
294-
App (Field (Var (V "make" 0)) (fieldSelectionLabel -> "file")) entry ->
292+
Make "file" entry ->
295293
FileEntry <$> extract (autoWith normalizer) entry
296294
expr -> Decode.typeError (expected (Decode.autoWith normalizer :: Decoder FilesystemEntry)) expr
297295
}

0 commit comments

Comments
 (0)