{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ViewPatterns #-}
module Dhall.Lint
(
lint
, removeUnusedBindings
, fixAssert
, fixParentPath
, addPreludeExtensions
, removeLetInLet
, useToMap
) where
import Control.Applicative ((<|>))
import Data.List.NonEmpty (NonEmpty (..))
import Dhall.Syntax
( Binding (..)
, Chunks (..)
, Directory (..)
, Expr (..)
, File (..)
, FilePrefix (..)
, Import (..)
, ImportHashed (..)
, ImportType (..)
, URL (..)
, Var (..)
, subExpressions
)
import qualified Data.Foldable as Foldable
import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.Map as Map
import qualified Data.Text as Text
import qualified Dhall.Core as Core
import qualified Dhall.Map
import qualified Dhall.Optics
import qualified Lens.Family
lint :: Eq s => Expr s Import -> Expr s Import
lint :: Expr s Import -> Expr s Import
lint = ASetter
(Expr s Import) (Expr s Import) (Expr s Import) (Expr s Import)
-> (Expr s Import -> Maybe (Expr s Import))
-> Expr s Import
-> Expr s Import
forall a b. ASetter a b a b -> (b -> Maybe a) -> a -> b
Dhall.Optics.rewriteOf ASetter
(Expr s Import) (Expr s Import) (Expr s Import) (Expr s Import)
forall (f :: * -> *) s a.
Applicative f =>
(Expr s a -> f (Expr s a)) -> Expr s a -> f (Expr s a)
subExpressions Expr s Import -> Maybe (Expr s Import)
forall s. Eq s => Expr s Import -> Maybe (Expr s Import)
rewrite
where
rewrite :: Expr s Import -> Maybe (Expr s Import)
rewrite Expr s Import
e =
Expr s Import -> Maybe (Expr s Import)
forall s a. Expr s a -> Maybe (Expr s a)
fixAssert Expr s Import
e
Maybe (Expr s Import)
-> Maybe (Expr s Import) -> Maybe (Expr s Import)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Expr s Import -> Maybe (Expr s Import)
forall a s. Eq a => Expr s a -> Maybe (Expr s a)
removeUnusedBindings Expr s Import
e
Maybe (Expr s Import)
-> Maybe (Expr s Import) -> Maybe (Expr s Import)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Expr s Import -> Maybe (Expr s Import)
forall s. Expr s Import -> Maybe (Expr s Import)
fixParentPath Expr s Import
e
Maybe (Expr s Import)
-> Maybe (Expr s Import) -> Maybe (Expr s Import)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Expr s Import -> Maybe (Expr s Import)
forall s a. Expr s a -> Maybe (Expr s a)
removeLetInLet Expr s Import
e
Maybe (Expr s Import)
-> Maybe (Expr s Import) -> Maybe (Expr s Import)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Expr s Import -> Maybe (Expr s Import)
forall s. Expr s Import -> Maybe (Expr s Import)
addPreludeExtensions Expr s Import
e
Maybe (Expr s Import)
-> Maybe (Expr s Import) -> Maybe (Expr s Import)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Expr s Import -> Maybe (Expr s Import)
forall s. Eq s => Expr s Import -> Maybe (Expr s Import)
sortImports Expr s Import
e
removeUnusedBindings :: Eq a => Expr s a -> Maybe (Expr s a)
removeUnusedBindings :: Expr s a -> Maybe (Expr s a)
removeUnusedBindings (Let (Binding Maybe s
_ Text
_ Maybe s
_ Maybe (Maybe s, Expr s a)
_ Maybe s
_ Expr s a
e) Expr s a
_)
| Expr s a -> Bool
forall s a. Expr s a -> Bool
isOrContainsAssert Expr s a
e = Maybe (Expr s a)
forall a. Maybe a
Nothing
removeUnusedBindings (Let (Binding Maybe s
_ Text
a Maybe s
_ Maybe (Maybe s, Expr s a)
_ Maybe s
_ Expr s a
_) Expr s a
d)
| Bool -> Bool
not (Text -> Int -> Var
V Text
a Int
0 Var -> Expr s a -> Bool
forall a s. Eq a => Var -> Expr s a -> Bool
`Core.freeIn` Expr s a
d) =
Expr s a -> Maybe (Expr s a)
forall a. a -> Maybe a
Just (Int -> Var -> Expr s a -> Expr s a
forall s a. Int -> Var -> Expr s a -> Expr s a
Core.shift (-Int
1) (Text -> Int -> Var
V Text
a Int
0) Expr s a
d)
removeUnusedBindings Expr s a
_ = Maybe (Expr s a)
forall a. Maybe a
Nothing
fixAssert :: Expr s a -> Maybe (Expr s a)
fixAssert :: Expr s a -> Maybe (Expr s a)
fixAssert (Let (Binding { value :: forall s a. Binding s a -> Expr s a
value = v :: Expr s a
v@(Expr s a -> Expr s a
forall s a. Expr s a -> Expr s a
Core.shallowDenote -> Equivalent {}), Maybe s
Maybe (Maybe s, Expr s a)
Text
bindingSrc2 :: forall s a. Binding s a -> Maybe s
annotation :: forall s a. Binding s a -> Maybe (Maybe s, Expr s a)
bindingSrc1 :: forall s a. Binding s a -> Maybe s
variable :: forall s a. Binding s a -> Text
bindingSrc0 :: forall s a. Binding s a -> Maybe s
bindingSrc2 :: Maybe s
annotation :: Maybe (Maybe s, Expr s a)
bindingSrc1 :: Maybe s
variable :: Text
bindingSrc0 :: Maybe s
..}) Expr s a
body) =
Expr s a -> Maybe (Expr s a)
forall a. a -> Maybe a
Just (Binding s a -> Expr s a -> Expr s a
forall s a. Binding s a -> Expr s a -> Expr s a
Let (Binding :: forall s a.
Maybe s
-> Text
-> Maybe s
-> Maybe (Maybe s, Expr s a)
-> Maybe s
-> Expr s a
-> Binding s a
Binding { value :: Expr s a
value = Expr s a -> Expr s a
forall s a. Expr s a -> Expr s a
Assert Expr s a
v, Maybe s
Maybe (Maybe s, Expr s a)
Text
bindingSrc2 :: Maybe s
annotation :: Maybe (Maybe s, Expr s a)
bindingSrc1 :: Maybe s
variable :: Text
bindingSrc0 :: Maybe s
bindingSrc2 :: Maybe s
annotation :: Maybe (Maybe s, Expr s a)
bindingSrc1 :: Maybe s
variable :: Text
bindingSrc0 :: Maybe s
.. }) Expr s a
body)
fixAssert (Let Binding s a
binding body :: Expr s a
body@(Expr s a -> Expr s a
forall s a. Expr s a -> Expr s a
Core.shallowDenote -> Equivalent {})) =
Expr s a -> Maybe (Expr s a)
forall a. a -> Maybe a
Just (Binding s a -> Expr s a -> Expr s a
forall s a. Binding s a -> Expr s a -> Expr s a
Let Binding s a
binding (Expr s a -> Expr s a
forall s a. Expr s a -> Expr s a
Assert Expr s a
body))
fixAssert Expr s a
_ =
Maybe (Expr s a)
forall a. Maybe a
Nothing
fixParentPath :: Expr s Import -> Maybe (Expr s Import)
fixParentPath :: Expr s Import -> Maybe (Expr s Import)
fixParentPath (Embed Import
oldImport) = do
let Import{ImportHashed
ImportMode
importMode :: Import -> ImportMode
importHashed :: Import -> ImportHashed
importMode :: ImportMode
importHashed :: ImportHashed
..} = Import
oldImport
let ImportHashed{Maybe SHA256Digest
ImportType
importType :: ImportHashed -> ImportType
hash :: ImportHashed -> Maybe SHA256Digest
importType :: ImportType
hash :: Maybe SHA256Digest
..} = ImportHashed
importHashed
case ImportType
importType of
Local FilePrefix
Here File{ directory :: File -> Directory
directory = Directory { [Text]
components :: Directory -> [Text]
components :: [Text]
components }, Text
file :: File -> Text
file :: Text
.. }
| Just NonEmpty Text
nonEmpty <- [Text] -> Maybe (NonEmpty Text)
forall a. [a] -> Maybe (NonEmpty a)
NonEmpty.nonEmpty [Text]
components
, NonEmpty Text -> Text
forall a. NonEmpty a -> a
NonEmpty.last NonEmpty Text
nonEmpty Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
".." -> do
let newDirectory :: Directory
newDirectory =
Directory :: [Text] -> Directory
Directory { components :: [Text]
components = NonEmpty Text -> [Text]
forall a. NonEmpty a -> [a]
NonEmpty.init NonEmpty Text
nonEmpty }
let newImportType :: ImportType
newImportType =
FilePrefix -> File -> ImportType
Local FilePrefix
Parent File :: Directory -> Text -> File
File{ directory :: Directory
directory = Directory
newDirectory, Text
file :: Text
file :: Text
.. }
let newImportHashed :: ImportHashed
newImportHashed =
ImportHashed :: Maybe SHA256Digest -> ImportType -> ImportHashed
ImportHashed { importType :: ImportType
importType = ImportType
newImportType, Maybe SHA256Digest
hash :: Maybe SHA256Digest
hash :: Maybe SHA256Digest
.. }
let newImport :: Import
newImport = Import :: ImportHashed -> ImportMode -> Import
Import { importHashed :: ImportHashed
importHashed = ImportHashed
newImportHashed, ImportMode
importMode :: ImportMode
importMode :: ImportMode
.. }
Expr s Import -> Maybe (Expr s Import)
forall a. a -> Maybe a
Just (Import -> Expr s Import
forall s a. a -> Expr s a
Embed Import
newImport)
ImportType
_ ->
Maybe (Expr s Import)
forall a. Maybe a
Nothing
fixParentPath Expr s Import
_ = Maybe (Expr s Import)
forall a. Maybe a
Nothing
addPreludeExtensions :: Expr s Import -> Maybe (Expr s Import)
addPreludeExtensions :: Expr s Import -> Maybe (Expr s Import)
addPreludeExtensions (Embed Import
oldImport) = do
let Import{ importHashed :: Import -> ImportHashed
importHashed = ImportHashed
oldImportHashed, ImportMode
importMode :: ImportMode
importMode :: Import -> ImportMode
.. } = Import
oldImport
let ImportHashed{ importType :: ImportHashed -> ImportType
importType = ImportType
oldImportType, Maybe SHA256Digest
hash :: Maybe SHA256Digest
hash :: ImportHashed -> Maybe SHA256Digest
.. } = ImportHashed
oldImportHashed
case ImportType
oldImportType of
Remote URL{ path :: URL -> File
path = File
oldPath, Maybe Text
Maybe (Expr Src Import)
Text
Scheme
headers :: URL -> Maybe (Expr Src Import)
query :: URL -> Maybe Text
authority :: URL -> Text
scheme :: URL -> Scheme
headers :: Maybe (Expr Src Import)
query :: Maybe Text
authority :: Text
scheme :: Scheme
..}
| Text
authority Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"prelude.dhall-lang.org" ->
case File
oldPath of
File{ file :: File -> Text
file = Text
oldFile, Directory
directory :: Directory
directory :: File -> Directory
.. }
| Bool -> Bool
not (Text -> Text -> Bool
Text.isSuffixOf Text
".dhall" Text
oldFile) -> do
let newFile :: Text
newFile = Text
oldFile Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".dhall"
let newPath :: File
newPath = File :: Directory -> Text -> File
File{ file :: Text
file = Text
newFile, Directory
directory :: Directory
directory :: Directory
.. }
let newImportType :: ImportType
newImportType = URL -> ImportType
Remote URL :: Scheme
-> Text -> File -> Maybe Text -> Maybe (Expr Src Import) -> URL
URL{ path :: File
path = File
newPath, Maybe Text
Maybe (Expr Src Import)
Text
Scheme
headers :: Maybe (Expr Src Import)
query :: Maybe Text
authority :: Text
scheme :: Scheme
headers :: Maybe (Expr Src Import)
query :: Maybe Text
authority :: Text
scheme :: Scheme
.. }
let newImportHashed :: ImportHashed
newImportHashed =
ImportHashed :: Maybe SHA256Digest -> ImportType -> ImportHashed
ImportHashed{ importType :: ImportType
importType = ImportType
newImportType, Maybe SHA256Digest
hash :: Maybe SHA256Digest
hash :: Maybe SHA256Digest
.. }
let newImport :: Import
newImport =
Import :: ImportHashed -> ImportMode -> Import
Import{ importHashed :: ImportHashed
importHashed = ImportHashed
newImportHashed, ImportMode
importMode :: ImportMode
importMode :: ImportMode
.. }
Expr s Import -> Maybe (Expr s Import)
forall (m :: * -> *) a. Monad m => a -> m a
return (Import -> Expr s Import
forall s a. a -> Expr s a
Embed Import
newImport)
File
_ ->
Maybe (Expr s Import)
forall a. Maybe a
Nothing
ImportType
_ -> do
Maybe (Expr s Import)
forall a. Maybe a
Nothing
addPreludeExtensions Expr s Import
_ = Maybe (Expr s Import)
forall a. Maybe a
Nothing
isOrContainsAssert :: Expr s a -> Bool
isOrContainsAssert :: Expr s a -> Bool
isOrContainsAssert (Assert Expr s a
_) = Bool
True
isOrContainsAssert Expr s a
e = FoldLike Any (Expr s a) (Expr s a) (Expr s a) (Expr s a)
-> (Expr s a -> Bool) -> Expr s a -> Bool
forall s t a b. FoldLike Any s t a b -> (a -> Bool) -> s -> Bool
Lens.Family.anyOf FoldLike Any (Expr s a) (Expr s a) (Expr s a) (Expr s a)
forall (f :: * -> *) s a.
Applicative f =>
(Expr s a -> f (Expr s a)) -> Expr s a -> f (Expr s a)
subExpressions Expr s a -> Bool
forall s a. Expr s a -> Bool
isOrContainsAssert Expr s a
e
removeLetInLet :: Expr s a -> Maybe (Expr s a)
removeLetInLet :: Expr s a -> Maybe (Expr s a)
removeLetInLet (Let Binding s a
binding (Note s
_ l :: Expr s a
l@Let{})) = Expr s a -> Maybe (Expr s a)
forall a. a -> Maybe a
Just (Binding s a -> Expr s a -> Expr s a
forall s a. Binding s a -> Expr s a -> Expr s a
Let Binding s a
binding Expr s a
l)
removeLetInLet Expr s a
_ = Maybe (Expr s a)
forall a. Maybe a
Nothing
useToMap :: Expr s a -> Maybe (Expr s a)
useToMap :: Expr s a -> Maybe (Expr s a)
useToMap
(ListLit
t :: Maybe (Expr s a)
t@(Just
(Expr s a -> Expr s a
forall s a. Expr s a -> Expr s a
Core.shallowDenote -> App
(Expr s a -> Expr s a
forall s a. Expr s a -> Expr s a
Core.shallowDenote -> Expr s a
List)
(Expr s a -> Expr s a
forall s a. Expr s a -> Expr s a
Core.shallowDenote -> Record
(Map Text (RecordField s a) -> Map Text (RecordField s a)
forall k v. Map k v -> Map k v
Dhall.Map.sort ->
[ ("mapKey", Core.shallowDenote . Core.recordFieldValue -> Text)
, ("mapValue", _)
]
)
)
)
)
[]
) =
Expr s a -> Maybe (Expr s a)
forall a. a -> Maybe a
Just (Expr s a -> Maybe (Expr s a) -> Expr s a
forall s a. Expr s a -> Maybe (Expr s a) -> Expr s a
ToMap (Map Text (RecordField s a) -> Expr s a
forall s a. Map Text (RecordField s a) -> Expr s a
RecordLit []) Maybe (Expr s a)
t)
useToMap (ListLit Maybe (Expr s a)
_ Seq (Expr s a)
keyValues)
| Bool -> Bool
not (Seq (Expr s a) -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Seq (Expr s a)
keyValues)
, Just Seq (Text, RecordField s a)
keyValues' <- (Expr s a -> Maybe (Text, RecordField s a))
-> Seq (Expr s a) -> Maybe (Seq (Text, RecordField s a))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Expr s a -> Maybe (Text, RecordField s a)
forall s a. Expr s a -> Maybe (Text, RecordField s a)
convert Seq (Expr s a)
keyValues =
Expr s a -> Maybe (Expr s a)
forall a. a -> Maybe a
Just
(Expr s a -> Maybe (Expr s a) -> Expr s a
forall s a. Expr s a -> Maybe (Expr s a) -> Expr s a
ToMap
(Map Text (RecordField s a) -> Expr s a
forall s a. Map Text (RecordField s a) -> Expr s a
RecordLit ([(Text, RecordField s a)] -> Map Text (RecordField s a)
forall k v. Ord k => [(k, v)] -> Map k v
Dhall.Map.fromList (Seq (Text, RecordField s a) -> [(Text, RecordField s a)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList Seq (Text, RecordField s a)
keyValues')))
Maybe (Expr s a)
forall a. Maybe a
Nothing
)
where
convert :: Expr s a -> Maybe (Text, RecordField s a)
convert Expr s a
keyValue =
case Expr s a -> Expr s a
forall s a. Expr s a -> Expr s a
Core.shallowDenote Expr s a
keyValue of
RecordLit
(Map Text (RecordField s a) -> Map Text (RecordField s a)
forall k v. Map k v -> Map k v
Dhall.Map.sort ->
[ ("mapKey" , Core.shallowDenote . Core.recordFieldValue -> TextLit (Chunks [] key))
, ("mapValue", value)
]
) ->
(Text, RecordField s a) -> Maybe (Text, RecordField s a)
forall a. a -> Maybe a
Just (Text
key, RecordField s a
value)
Expr s a
_ ->
Maybe (Text, RecordField s a)
forall a. Maybe a
Nothing
useToMap Expr s a
_ =
Maybe (Expr s a)
forall a. Maybe a
Nothing
sortImports :: Eq s => Expr s Import -> Maybe (Expr s Import)
sortImports :: Expr s Import -> Maybe (Expr s Import)
sortImports oldExpression :: Expr s Import
oldExpression@(Let Binding s Import
binding0 Expr s Import
oldBody0)
| Expr s Import
oldExpression Expr s Import -> Expr s Import -> Bool
forall a. Eq a => a -> a -> Bool
== Expr s Import
newExpression = Maybe (Expr s Import)
forall a. Maybe a
Nothing
| Bool
otherwise = Expr s Import -> Maybe (Expr s Import)
forall a. a -> Maybe a
Just Expr s Import
newExpression
where
toBool :: Expr s a -> Bool
toBool (Embed a
_ ) = Bool
False
toBool (Note s
_ Expr s a
e) = Expr s a -> Bool
toBool Expr s a
e
toBool Expr s a
_ = Bool
True
process :: (Map Text Int, Int)
-> Binding s a
-> Expr s a
-> (Expr s a -> Expr s a)
-> ((Int, Expr s a -> Expr s a), [(Int, Expr s a -> Expr s a)],
Expr s a)
process (Map Text Int
seen, Int
index) Binding{Maybe s
Maybe (Maybe s, Expr s a)
Text
Expr s a
value :: Expr s a
bindingSrc2 :: Maybe s
annotation :: Maybe (Maybe s, Expr s a)
bindingSrc1 :: Maybe s
variable :: Text
bindingSrc0 :: Maybe s
bindingSrc2 :: forall s a. Binding s a -> Maybe s
annotation :: forall s a. Binding s a -> Maybe (Maybe s, Expr s a)
bindingSrc1 :: forall s a. Binding s a -> Maybe s
variable :: forall s a. Binding s a -> Text
bindingSrc0 :: forall s a. Binding s a -> Maybe s
value :: forall s a. Binding s a -> Expr s a
..} Expr s a
oldBody Expr s a -> Expr s a
function = ((Int, Expr s a -> Expr s a)
pair, [(Int, Expr s a -> Expr s a)]
pairs, Expr s a
newBody)
where
order :: Int
order =
if Bool
b then Int
index else Int -> Text -> Map Text Int -> Int
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault (Int
0 :: Int) Text
variable Map Text Int
seen
b :: Bool
b = Expr s a -> Bool
forall s a. Expr s a -> Bool
toBool Expr s a
value
pair :: (Int, Expr s a -> Expr s a)
pair = (Int
order, Expr s a -> Expr s a
function)
~([(Int, Expr s a -> Expr s a)]
pairs, Expr s a
newBody) =
(Map Text Int, Int)
-> Expr s a -> ([(Int, Expr s a -> Expr s a)], Expr s a)
label (Text -> Int -> Map Text Int -> Map Text Int
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Text
variable Int
order Map Text Int
seen, Int
index Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Expr s a
oldBody
label :: (Map Text Int, Int)
-> Expr s a -> ([(Int, Expr s a -> Expr s a)], Expr s a)
label (Map Text Int, Int)
state (Let Binding s a
binding Expr s a
oldBody) = ((Int, Expr s a -> Expr s a)
pair (Int, Expr s a -> Expr s a)
-> [(Int, Expr s a -> Expr s a)] -> [(Int, Expr s a -> Expr s a)]
forall a. a -> [a] -> [a]
: [(Int, Expr s a -> Expr s a)]
pairs, Expr s a
newBody)
where
function :: Expr s a -> Expr s a
function = Binding s a -> Expr s a -> Expr s a
forall s a. Binding s a -> Expr s a -> Expr s a
Let Binding s a
binding
~((Int, Expr s a -> Expr s a)
pair, [(Int, Expr s a -> Expr s a)]
pairs, Expr s a
newBody) = (Map Text Int, Int)
-> Binding s a
-> Expr s a
-> (Expr s a -> Expr s a)
-> ((Int, Expr s a -> Expr s a), [(Int, Expr s a -> Expr s a)],
Expr s a)
process (Map Text Int, Int)
state Binding s a
binding Expr s a
oldBody Expr s a -> Expr s a
function
label (Map Text Int, Int)
state (Note s
src (Let Binding s a
binding Expr s a
oldBody)) = ((Int, Expr s a -> Expr s a)
pair (Int, Expr s a -> Expr s a)
-> [(Int, Expr s a -> Expr s a)] -> [(Int, Expr s a -> Expr s a)]
forall a. a -> [a] -> [a]
: [(Int, Expr s a -> Expr s a)]
pairs, Expr s a
newBody)
where
function :: Expr s a -> Expr s a
function Expr s a
e = s -> Expr s a -> Expr s a
forall s a. s -> Expr s a -> Expr s a
Note s
src (Binding s a -> Expr s a -> Expr s a
forall s a. Binding s a -> Expr s a -> Expr s a
Let Binding s a
binding Expr s a
e)
~((Int, Expr s a -> Expr s a)
pair, [(Int, Expr s a -> Expr s a)]
pairs, Expr s a
newBody) = (Map Text Int, Int)
-> Binding s a
-> Expr s a
-> (Expr s a -> Expr s a)
-> ((Int, Expr s a -> Expr s a), [(Int, Expr s a -> Expr s a)],
Expr s a)
process (Map Text Int, Int)
state Binding s a
binding Expr s a
oldBody Expr s a -> Expr s a
function
label (Map Text Int, Int)
_ Expr s a
body =
([], Expr s a
body)
~(NonEmpty (Int, Expr s Import -> Expr s Import)
pairs0, Expr s Import
newBody0) = ((Int, Expr s Import -> Expr s Import)
pair (Int, Expr s Import -> Expr s Import)
-> [(Int, Expr s Import -> Expr s Import)]
-> NonEmpty (Int, Expr s Import -> Expr s Import)
forall a. a -> [a] -> NonEmpty a
:| [(Int, Expr s Import -> Expr s Import)]
pairs, Expr s Import
newBody)
where
function :: Expr s Import -> Expr s Import
function = Binding s Import -> Expr s Import -> Expr s Import
forall s a. Binding s a -> Expr s a -> Expr s a
Let Binding s Import
binding0
~((Int, Expr s Import -> Expr s Import)
pair, [(Int, Expr s Import -> Expr s Import)]
pairs, Expr s Import
newBody) =
(Map Text Int, Int)
-> Binding s Import
-> Expr s Import
-> (Expr s Import -> Expr s Import)
-> ((Int, Expr s Import -> Expr s Import),
[(Int, Expr s Import -> Expr s Import)], Expr s Import)
forall s a.
(Map Text Int, Int)
-> Binding s a
-> Expr s a
-> (Expr s a -> Expr s a)
-> ((Int, Expr s a -> Expr s a), [(Int, Expr s a -> Expr s a)],
Expr s a)
process (Map Text Int
forall k a. Map k a
Map.empty, Int
1) Binding s Import
binding0 Expr s Import
oldBody0 Expr s Import -> Expr s Import
function
sortedFunctions :: NonEmpty (Expr s Import -> Expr s Import)
sortedFunctions = ((Int, Expr s Import -> Expr s Import)
-> Expr s Import -> Expr s Import)
-> NonEmpty (Int, Expr s Import -> Expr s Import)
-> NonEmpty (Expr s Import -> Expr s Import)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int, Expr s Import -> Expr s Import)
-> Expr s Import -> Expr s Import
forall a b. (a, b) -> b
snd (((Int, Expr s Import -> Expr s Import) -> Int)
-> NonEmpty (Int, Expr s Import -> Expr s Import)
-> NonEmpty (Int, Expr s Import -> Expr s Import)
forall o a. Ord o => (a -> o) -> NonEmpty a -> NonEmpty a
NonEmpty.sortWith (Int, Expr s Import -> Expr s Import) -> Int
forall a b. (a, b) -> a
fst NonEmpty (Int, Expr s Import -> Expr s Import)
pairs0)
newExpression :: Expr s Import
newExpression = ((Expr s Import -> Expr s Import)
-> Expr s Import -> Expr s Import)
-> Expr s Import
-> NonEmpty (Expr s Import -> Expr s Import)
-> Expr s Import
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Expr s Import -> Expr s Import) -> Expr s Import -> Expr s Import
forall a. a -> a
id Expr s Import
newBody0 NonEmpty (Expr s Import -> Expr s Import)
sortedFunctions
sortImports Expr s Import
_ = Maybe (Expr s Import)
forall a. Maybe a
Nothing