diff --git a/.github/workflows/hlint.yaml b/.github/workflows/hlint.yaml index 39de47b3..1087af2a 100644 --- a/.github/workflows/hlint.yaml +++ b/.github/workflows/hlint.yaml @@ -1,6 +1,9 @@ name: Brat CI on: - pull_request: [] + pull_request: + branches: [ main ] + paths: + - "**.hs" jobs: hlint: diff --git a/brat/.hlint.yaml b/brat/.hlint.yaml index e9080188..cf03cb42 100644 --- a/brat/.hlint.yaml +++ b/brat/.hlint.yaml @@ -66,7 +66,9 @@ - ignore: {name: Use newtype instead of data} - ignore: {name: Fuse foldr/<$>} - ignore: {name: Redundant bracket, within: Brat.Syntax.Value} +- ignore: {name: Redundant bracket, within: Data.HugrGraph} - ignore: {name: Avoid NonEmpty.unzip} # Buggy - false positives +- ignore: {name: Redundant <&>} # Often making things worse # Define some custom infix operators # - fixity: infixr 3 ~^#^~ diff --git a/brat/Brat/Checker.hs b/brat/Brat/Checker.hs index 9f3f8315..4d6e3dcf 100644 --- a/brat/Brat/Checker.hs +++ b/brat/Brat/Checker.hs @@ -757,7 +757,7 @@ checkClause my fnName cty clause = modily my $ do trackM $ "[[[[[[TestMatchData\n" ++ show match ++ "\n]]]]]]" pure (sol, match, patRo :->> outRo, fmap (Some . (patEz :*) . abstractEndz patEz) <$> defs) - for defs $ \((name, kind), Some (_ :* val)) -> trackM ("Def: " ++ show ((name, kind), val)) + for_ defs $ \((name, kind), Some (_ :* val)) -> trackM ("Def: " ++ show ((name, kind), val)) -- Now actually make a box for the RHS and check it ((boxPort, _ty), _) <- let ?my = my in makeBox (clauseName ++ "_rhs") rhsCty $ \(rhsOvers, rhsUnders) -> do @@ -780,7 +780,7 @@ checkClause my fnName cty clause = modily my $ do -- would arise if we've not yet defined the outer src let vars = fst <$> sol env <- mkEnv vars rhsOvers - (localEnv (env <> defs) $ "$rhs" -! check @m (rhs clause) ((), rhsUnders)) + localEnv (env <> defs) $ "$rhs" -! check @m (rhs clause) ((), rhsUnders) let NamedPort {end=Ex rhsNode _} = boxPort pure (match, rhsNode) where @@ -804,8 +804,8 @@ checkClause my fnName cty clause = modily my $ do outPorts <- depOutPorts def srcAndTys <- for outPorts (\outport -> (NamedPort outport "",) <$> typeOfEnd Braty (ExEnd outport)) zx <- pure $ foldl (\sol srcAndTy -> insert ("$" ++ show (end (fst srcAndTy)), srcAndTy) sol) zx srcAndTys - (sol, defs) <- worker (zx {-:< entry-}) sol - pure ({-(patVar, (src, Left k)):-}sol, ((patVar, k), def):defs) + (sol, defs) <- worker zx sol + pure (sol, ((patVar, k), def):defs) -- Pat vars beginning with '_' aren't in scope, we can ignore them -- (but if they're kinded they might come up later as the dependency of something else) worker zx (('_':_, _):sol) = worker zx sol @@ -1085,7 +1085,7 @@ kindCheckRow' :: forall m n -> Checking (Int, VEnv, Some (Endz :* Ro m n)) kindCheckRow' _ ez env (_,i) [] = pure (i, env, Some (ez :* R0)) -kindCheckRow' my nys env (name, i) ((Anon ty):rest) = kindCheckRow' my nys env (name, i) ((Named (show i) ty):rest) +kindCheckRow' my nys env (name, i) ((Anon ty):rest) = kindCheckRow' my nys env (name, i) (Named (show i) ty:rest) kindCheckRow' Braty (ny :* s) env (name,i) ((Named p (Left k)):rest) = do -- s is Stack Z n let dangling = Ex name (ny2int ny) req (Declare (ExEnd dangling) Braty (Left k) Definable) -- assume none are SkolemConst?? @@ -1287,6 +1287,6 @@ runChecking ve initStore ns m = do -- show multiple error locations hs@((_,fc):_) -> Left $ Err (Just fc) (RemainingNatHopes (show . fst <$> hs)) where - isNatKinded tyMap e = case tyMap M.! (InEnd e) of + isNatKinded tyMap e = case tyMap M.! InEnd e of (EndType Braty (Left Nat), _) -> True _ -> False diff --git a/brat/Brat/Checker/Helpers.hs b/brat/Brat/Checker/Helpers.hs index 8b37a57e..485cf9d0 100644 --- a/brat/Brat/Checker/Helpers.hs +++ b/brat/Brat/Checker/Helpers.hs @@ -692,6 +692,7 @@ valPats2Val (k:ks) (v:vs) = do valPats2Val [] [] = pure (B0, []) valPats2Val _ _ = err $ InternalError "Type args didn't match expected - kindCheck should've sorted it" +{-# ANN traceChecking ("HLint: ignore Redundant pure" :: String) #-} traceChecking :: String -> (a -> Checking b) -> (a -> Checking b) traceChecking _lbl m a = do -- trackM ("Enter " ++ lbl ++ ": " ++ show a) diff --git a/brat/Brat/Checker/Monad.hs b/brat/Brat/Checker/Monad.hs index 26060ae8..8c5b7592 100644 --- a/brat/Brat/Checker/Monad.hs +++ b/brat/Brat/Checker/Monad.hs @@ -136,7 +136,7 @@ wrapper f (Yield st k) = Yield st (wrapper f . k) wrapper f (Fork d par c) = Fork d (wrapper f par) (wrapper f c) wrapper2 :: (forall a. CheckingSig a -> Maybe a) -> Checking v -> Checking v -wrapper2 f = wrapper (\s -> pure (f s)) +wrapper2 f = wrapper (pure . f) localAlias :: (QualName, Alias) -> Checking v -> Checking v localAlias (name, alias) = wrapper2 (\case @@ -147,7 +147,7 @@ localFC :: FC -> Checking v -> Checking v localFC f = wrapper (\case AskFC -> pure $ Just f (Throw e@Err{fc=Nothing}) -> req (Throw (e{fc=Just f})) >> error "Throw returned" - _ -> pure $ Nothing) + _ -> pure Nothing) localEnv :: (?my :: Modey m) => Env (EnvData m) -> Checking v -> Checking v localEnv = case ?my of @@ -172,7 +172,7 @@ captureOuterLocals n c = do where helper :: VEnv -> forall a. CheckingSig a -> Checking (Maybe a) helper avail (VLup x) | j@(Just new) <- M.lookup x avail = - (req $ AddCapture n (x,new)) >> (pure $ Just j) + req (AddCapture n (x,new)) >> pure (Just j) helper _ _ = pure Nothing wrapError :: (Error -> Error) -> Checking v -> Checking v @@ -272,7 +272,7 @@ handler (Req s k) ctx AskNS -> error "AskNS in handler, should only happen under `-!`" Throw err -> Left err LogHole hole -> do (v,ctx,holes) <- handler (k ()) ctx - return (v,ctx,(hole:holes)) + return (v,ctx,hole:holes) AskFC -> error "AskFC in handler - shouldn't happen, should always be in localFC" VLup s -> handler (k $ M.lookup s (globalVEnv ctx)) ctx ALup s -> handler (k $ M.lookup s (aliasTable ctx)) ctx @@ -350,7 +350,7 @@ handler (Define lbl end v k) ctx = let st@Store{typeMap=tm, valueMap=vm} = store InEnd inport -> case M.lookup inport (dynamicSet ctx) of Just fc -> track ("Replace " ++ show end ++ " with " ++ show newDynamics) $ M.union - (M.fromList (zip newDynamics (repeat fc))) + (M.fromList (map (, fc) newDynamics)) (M.delete inport (dynamicSet ctx)) Nothing -> dynamicSet ctx }) diff --git a/brat/Brat/Checker/SolveNumbers.hs b/brat/Brat/Checker/SolveNumbers.hs index 8089c506..8ce2fb6b 100644 --- a/brat/Brat/Checker/SolveNumbers.hs +++ b/brat/Brat/Checker/SolveNumbers.hs @@ -64,13 +64,13 @@ solveNumMeta mine e nv = case (e, numVars nv) of unifyNum :: (End -> Maybe String) -> NumVal (VVar Z) -> NumVal (VVar Z) -> Checking () unifyNum mine nv0 nv1 = do - trailM $ ("unifyNum In\n " ++ show nv0 ++ "\n " ++ show nv1) + trailM ("unifyNum In\n " ++ show nv0 ++ "\n " ++ show nv1) nv0 <- numEval S0 nv0 nv1 <- numEval S0 nv1 unifyNum' mine (quoteNum Zy nv0) (quoteNum Zy nv1) nv0 <- numEval S0 (quoteNum Zy nv0) nv1 <- numEval S0 (quoteNum Zy nv1) - trailM $ ("unifyNum Out\n " ++ show (quoteNum Zy nv0) ++ "\n " ++ show (quoteNum Zy nv1)) + trailM ("unifyNum Out\n " ++ show (quoteNum Zy nv0) ++ "\n " ++ show (quoteNum Zy nv1)) -- Need to keep track of which way we're solving - which side is known/unknown -- Things which are dynamically unknown must be Tgts - information flows from Srcs @@ -101,14 +101,14 @@ unifyNum' mine (NumValue lup lgro) (NumValue rup rgro) (VPar e@(InEnd p), VPar e'@(ExEnd dangling)) | Just _ <- mine e -> do req (Wire (dangling, TNat, p)) - defineTgt' ("flex-flex In Ex") (NamedPort p "") (VNum (nVar v')) + defineTgt' "flex-flex In Ex" (NamedPort p "") (VNum (nVar v')) | Just _ <- mine e' -> do req (Wire (dangling, TNat, p)) - defineSrc' ("flex-flex In Ex") (NamedPort dangling "") (VNum (nVar v)) + defineSrc' "flex-flex In Ex" (NamedPort dangling "") (VNum (nVar v)) | otherwise -> mkYield "flexFlex" (S.singleton e) >> unifyNum mine (nVar v) (nVar v') (VPar e@(InEnd p), VPar e'@(InEnd p')) | Just _ <- mine e -> defineTgt' "flex-flex In In1" (NamedPort p "") (VNum (nVar v')) - | Just _ <- mine e' -> defineTgt' "flex-flex In In0"(NamedPort p' "") (VNum (nVar v)) + | Just _ <- mine e' -> defineTgt' "flex-flex In In0" (NamedPort p' "") (VNum (nVar v)) | otherwise -> mkYield "flexFlex" (S.fromList [e, e']) >> unifyNum mine (nVar v) (nVar v') lhsStrictMono :: StrictMono (VVar Z) -> NumVal (VVar Z) -> Checking () @@ -159,7 +159,7 @@ unifyNum' mine (NumValue lup lgro) (NumValue rup rgro) -- = 2^k + 2^k * y -- Hence, the predecessor is (2^k - 1) + (2^k * y) demandSucc (NumValue k x) | k > 0 = pure (NumValue (k - 1) x) - demandSucc (NumValue 0 (StrictMonoFun (mono@(StrictMono k (Linear (VPar e)))))) + demandSucc (NumValue 0 (StrictMonoFun mono@(StrictMono k (Linear (VPar e))))) | Just loc <- mine e = do pred <- loc -! traceChecking "makePred" makePred e pure (nPlus ((2^k) - 1) (nVar (VPar pred))) diff --git a/brat/Brat/Compile/Hugr.hs b/brat/Brat/Compile/Hugr.hs index ec0e7d2d..c81f2846 100644 --- a/brat/Brat/Compile/Hugr.hs +++ b/brat/Brat/Compile/Hugr.hs @@ -115,12 +115,12 @@ addHole parent sig outPort = do hole <- gets (length . holes) -- but anyway h <- addNode ("hole " ++ show hole) (parent, OpCustom (holeOp hole sig)) st <- get - put (st { holes = (holes st) :< (h, outPort)}) + put (st { holes = holes st :< (h, outPort)}) pure h filePrefix :: [String] -> Name -> Maybe Name filePrefix prefixes (MkName (("checking",_):_filename:ns)) = - hasPrefix (["globals"]++prefixes) (MkName ns) + hasPrefix ("globals" : prefixes) (MkName ns) runCheckingInCompile :: Free CheckingSig t -> Compile t runCheckingInCompile (Ret t) = pure t @@ -259,15 +259,14 @@ compileTarget parent tgtN tgt = do edges <- compileInEdges parent tgt -- registerCompiled tgt tgtN -- really shouldn't be necessary, not reachable for_ edges (\(src, tgtPort) -> addEdge (src, Port tgtN tgtPort)) - pure () -in_edges :: Name -> Compile [((OutPort, Val Z), Int)] -in_edges name = gets bratGraph <&> \(_, es) -> [((src, ty), portNum) | (src, ty, In edgTgt portNum) <- es, edgTgt == name] +inEdges :: Name -> Compile [((OutPort, Val Z), Int)] +inEdges name = gets bratGraph <&> \(_, es) -> [((src, ty), portNum) | (src, ty, In edgTgt portNum) <- es, edgTgt == name] compileInEdges :: NodeId -> Name -> Compile [(PortId NodeId, Int)] compileInEdges parent name = do - in_edges <- in_edges name - catMaybes <$> for in_edges (\((src, _), tgtPort) -> getOutPort parent src <&> fmap (, tgtPort)) + inEdges <- inEdges name + catMaybes <$> for inEdges (\((src, _), tgtPort) -> getOutPort parent src <&> fmap (, tgtPort)) compileWithInputs :: NodeId -> Name -> Compile (Maybe NodeId) compileWithInputs parent name = gets (M.lookup name . compiled) >>= \case @@ -283,14 +282,14 @@ compileWithInputs parent name = gets (M.lookup name . compiled) >>= \case -- If we only care about the node for typechecking, then drop it and return `Nothing`. -- Otherwise, NodeId of compiled node, and list of Hugr in-edges (source and target-port) compileNode :: Compile (Maybe (NodeId, [(PortId NodeId, Int)])) - compileNode = case (filePrefix ["decl"] name) of + compileNode = case filePrefix ["decl"] name of Just _ -> error "Kernel contained call to global; should have been a splice" _ -> do (ns, _) <- gets bratGraph let node = ns M.! name trackM ("compileNode (" ++ show parent ++ ") " ++ show name ++ " " ++ show node) nod_edge_info <- case node of - (BratNode _ _ _) -> error "Can't compile classical Brat" + (BratNode {}) -> error "Can't compile classical Brat" (KernelNode thing ins outs) -> compileNode' thing ins outs case nod_edge_info of Nothing -> pure Nothing @@ -323,7 +322,7 @@ compileWithInputs parent name = gets (M.lookup name . compiled) >>= \case Nothing -> addHole parent sig outPort Source -> error "Source found outside of compileBox" - + Target -> error "Target found outside of compileBox" Id | Nothing <- filePrefix ["decl"] name -> default_edges <$> do @@ -500,10 +499,10 @@ makeConditional :: String -- Label makeConditional lbl parent discrim otherInputs cases = do condId <- freshNode "Conditional" parent let rows = getSumVariants (snd discrim) - (outTyss_cases) <- for (zip (zip [0..] cases) rows) (\((ix, (name, f)), row) -> makeCase condId name ix (row ++ (snd <$> otherInputs)) f) + outTyss_cases <- for (zip (zip [0..] cases) rows) (\((ix, (name, f)), row) -> makeCase condId name ix (row ++ (snd <$> otherInputs)) f) let outTys = if allRowsEqual (fst <$> outTyss_cases) then fst (head outTyss_cases) - else (error "Conditional output types didn't match") + else error "Conditional output types didn't match" let condOp = OpConditional (Conditional rows (snd <$> otherInputs) outTys [("label", lbl)]) setOp condId condOp onHugr $ H.setFirstChildren condId (snd <$> outTyss_cases) diff --git a/brat/Brat/Compiler.hs b/brat/Brat/Compiler.hs index 9fee6a53..afc29d83 100644 --- a/brat/Brat/Compiler.hs +++ b/brat/Brat/Compiler.hs @@ -20,13 +20,13 @@ import Brat.Syntax.Port (NamedPort(..), OutPort(..), InPort(..)) import Brat.Syntax.Value (Val(VFun)) import Control.Exception (evaluate) -import Control.Monad (forM, when) +import Control.Monad (forM_, when) import Control.Monad.Except import Data.List (intercalate) import qualified Data.Map as M import qualified Data.ByteString.Lazy as BS import Data.Foldable (for_) -import Data.HugrGraph (HugrGraph, NodeId, to_json) +import Data.HugrGraph (HugrGraph, NodeId, toJson) import System.Exit (die) printDeclsHoles :: [FilePath] -> String -> IO () @@ -34,7 +34,7 @@ printDeclsHoles libDirs file = do env <- runExceptT $ loadFilename root libDirs file (declEnv, holes, _, _, _) <- eitherIO env putStrLn "Decls:" - forM (M.toList declEnv) $ \(name, (src_tys, _vdecl)) -> + forM_ (M.toList declEnv) $ \(name, (src_tys, _vdecl)) -> putStrLn $ show name ++ " :: " ++ intercalate ", " (map (show . snd) src_tys) putStrLn "" putStrLn "Holes:" @@ -94,16 +94,16 @@ compileFile libDirs file = do (newRoot, (declEnv, holes, st, outerGraph, _)) <- compileToGraph libDirs file let venv = M.map fst declEnv case holes of - [] -> let box_decls = (M.keys declEnv) >>= (findBoxes venv outerGraph) - in Right <$> (evaluate -- turns 'error' into IO 'die' - $ M.fromList [(n, let (hugr, holes) = compileKernel (newRoot, st, outerGraph) "root" n - in (hugr, map fst holes)) - | n <- box_decls]) + [] -> let box_decls = M.keys declEnv >>= findBoxes venv outerGraph + in Right <$> evaluate -- turns 'error' into IO 'die' + (M.fromList [(n, let (hugr, holes) = compileKernel (newRoot, st, outerGraph) "root" n + in (hugr, map fst holes)) + | n <- box_decls]) hs -> pure $ Left (CompilingHoles hs) where findBoxes :: VEnv -> Graph -> QualName -> [Name] findBoxes venv (ns, es) name = case M.lookup name venv of - Nothing -> error $ (show name) ++ ".... not found in VEnv" + Nothing -> error $ show name ++ ".... not found in VEnv" Just vals -> vals >>= \(NamedPort (Ex n _) _, _) -> case M.lookup n ns of Just (BratNode Id _ _) -> [src | (Ex src 0, _, In tgt _) <- es, tgt == n, isKernelBox src ns] @@ -117,6 +117,6 @@ compileAndPrintFile :: [FilePath] -> String -> IO () compileAndPrintFile libDirs file = compileFile libDirs file >>= \case Right hs -> for_ (M.toList hs) $ \(n, (hugr, splices)) -> do putStrLn $ "Compiled box: " ++ show n - BS.putStr (to_json hugr) + BS.putStr (toJson hugr) putStrLn $ "With splices: " ++ show splices Left err -> die (show err) diff --git a/brat/Brat/Dot.hs b/brat/Brat/Dot.hs index 8c97e767..46f9e09c 100644 --- a/brat/Brat/Dot.hs +++ b/brat/Brat/Dot.hs @@ -15,10 +15,9 @@ import qualified Data.Map as M import qualified Data.Set as S import Data.List.NonEmpty (NonEmpty(..)) import Data.Text.Lazy (pack, unpack) -import Data.Maybe (fromMaybe) +import Data.Maybe ( fromMaybe, fromJust ) import Data.Bifunctor (first) import Data.Graph (reachable, transposeG) -import Data.Maybe (fromJust) import Data.Tuple.HT (snd3) @@ -57,7 +56,7 @@ toDotString (ns,ws) cs = unpack . GV.printDotGraph $ GV.graphElemsToDot params v getRefEdge x (KernelNode (Splice (Ex y _)) _ _) = [(Name' y, x, EvalEdge)] getRefEdge x (BratNode (Box src tgt) _ _) = [(x, Name' src, SrcEdge), (x, Name' tgt, SrcEdge)] getRefEdge x (BratNode (PatternMatch (p:|pats)) _ _) = - [ (x, Name' innerBox, CaseEdge) | (_, innerBox) <- (p:pats) ] + [ (x, Name' innerBox, CaseEdge) | (_, innerBox) <- p:pats ] getRefEdge _ _ = [] -- Map from node to cluster. Clusters are identified by their containing Box node. diff --git a/brat/Brat/Eval.hs b/brat/Brat/Eval.hs index d7ee14c6..824f165e 100644 --- a/brat/Brat/Eval.hs +++ b/brat/Brat/Eval.hs @@ -134,7 +134,7 @@ quoteCTy lvy my ga (ins :->> outs) = quoteRo my ga ins lvy >>= \case (_, Some (outs' :* _)) -> pure (ins' :->> outs') quoteNum :: Ny lv -> NumVal SVar -> NumVal (VVar lv) -quoteNum lvy num = fmap (quoteVar lvy) num +quoteNum lvy = fmap (quoteVar lvy) -- first number is next Lvl to use in Value -- require every Lvl in Sem is < n (converted by n - 1 - lvl), else must fail at runtime diff --git a/brat/Brat/Load.hs b/brat/Brat/Load.hs index 5a0267e6..aa98cbf7 100644 --- a/brat/Brat/Load.hs +++ b/brat/Brat/Load.hs @@ -155,7 +155,7 @@ loadStmtsWithEnv ns (oldDeclEnv, oldHoles, oldStore, oldGraph, oldCaps) (fname, (_, unders, overs, _) <- prefix -! next (show name) thing (S0, Some (Zy :* S0)) ins outs pure ((name, VDecl d{fnSig=sig}), (unders, overs)) trackM "finished kind checking" - unless (length holes == 0) $ error "Should be no holes from kind-checking" + unless (null holes) $ error "Should be no holes from kind-checking" unless (M.null capSets) $ error "Should be no captures from kind-checking" -- A list of local functions (read: with bodies) to define with checkDecl let to_define = M.fromList [ (name, unders) | ((name, VDecl decl), (unders, _)) <- entries, fnLocality decl == Local ] diff --git a/brat/Brat/Machine.hs b/brat/Brat/Machine.hs index a6b0c8fc..6ae9262e 100644 --- a/brat/Brat/Machine.hs +++ b/brat/Brat/Machine.hs @@ -33,11 +33,11 @@ runInterpreter libDirs file runFunc = do (root, (declEnv, _, st, outerGraph, capSets)) <- compileToGraph libDirs file let venv = M.map fst declEnv --print (show outerGraph) - let outPorts = [op | (NamedPort op _, _ty) <- venv M.! (plain runFunc)] + let outPorts = [op | (NamedPort op _, _ty) <- venv M.! plain runFunc] let outTask = evalPorts (outerGraph, st, root, capSets) (B0 :< BratValues M.empty) B0 outPorts -- we hope outTask is a Finished. Or a Suspend. pure $ case outTask of - Finished [(KernelV hugr)] -> Right hugr + Finished [KernelV hugr] -> Right hugr _ -> Left $ T.pack $ show outTask data Frame where @@ -124,8 +124,8 @@ evalNodeInputs gi fz name = -- might be good to check M.keys == [0,1,....] here evalPorts gi fz B0 (getNodeInputs gi name) -updateCache (fz :< BratValues env) port_vals = fz :< (BratValues $ foldr (uncurry M.insert) env port_vals) -updateCache (fz :< f) pvs = (updateCache fz pvs) :< f +updateCache (fz :< BratValues env) port_vals = fz :< BratValues (foldr (uncurry M.insert) env port_vals) +updateCache (fz :< f) pvs = updateCache fz pvs :< f -- updateCache B0 pvs = B0 :< (M.fromList pvs) evalSplices :: GraphInfo -> Bwd Frame -> HG.HugrGraph HG.NodeId -> [(HG.NodeId, OutPort)] -> Task @@ -143,7 +143,7 @@ runVectorisedThunks gi fz [] outs = run gi fz (Finished $ transposeRows2V $ outs transposeRows2V rows = let rows' = map uncons rows in if all isNothing rows' then [] - else let (hds, tls) = unzip (map fromJust rows') in (VecV hds) : (transposeRows2V tls) + else let (hds, tls) = unzip (map fromJust rows') in VecV hds : transposeRows2V tls runVectorisedThunks gi fz ((th, inputs):ths) outs = runThunk gi (fz :< VectorisedFuncs ths outs) th inputs @@ -153,7 +153,7 @@ run :: GraphInfo -> Bwd Frame -> Task -> Task runThunk :: GraphInfo -> Bwd Frame -> BratThunk -> [Value] -> Task runThunk gi fz (BratClosure env src tgt) inputs = let env_with_args = foldr (uncurry M.insert) env [(Ex src off, val) | (off, val) <- zip [0..] inputs] - in evalNodeInputs gi (fz :< (BratValues env_with_args)) tgt + in evalNodeInputs gi (fz :< BratValues env_with_args) tgt runThunk (g,st,ns,cs) fz (BratPrim ext op _cty) inputs | (hugrNS,newRoot) <- split "hugr" ns, Just outs <- runPrim hugrNS (ext,op) inputs = run (g,st,newRoot,cs) fz (Finished outs) runThunk gi fz (VectorisedThunks ths) inputs = @@ -164,7 +164,7 @@ runThunk gi fz (VectorisedThunks ths) inputs = transposeV2Rows :: [Value] -> [[Value]] transposeV2Rows vs | all isEmptyVecV vs = [] - | otherwise = let (hds, tls) = unzip $ map (\(VecV (hd:tl)) -> (hd, VecV tl)) vs in hds : (transposeV2Rows tls) + | otherwise = let (hds, tls) = unzip $ map (\(VecV (hd:tl)) -> (hd, VecV tl)) vs in hds : transposeV2Rows tls isEmptyVecV :: Value -> Bool isEmptyVecV (VecV []) = True isEmptyVecV _ = False @@ -192,7 +192,7 @@ evalNode gi@(g@(nodes, _), st, root, cs) fz n ins = case nodes M.! n of (BratNode (Selector stor) _ _) -> case (stor, ins) of (PrefixName [] "cons", [VecV (x:xs)]) -> run gi fz (Finished [x, VecV xs]) (BratNode Replicate _ _) -> case ins of - [IntV n, elem] -> run gi fz (Finished [(VecV (replicate n elem))]) + [IntV n, elem] -> run gi fz (Finished [VecV (replicate n elem)]) (BratNode MapFun _ _) -> case ins of -- We have a vector (or vec of vecs, n-dimensions) of functions [IntV len, VecV funs] -> run gi fz (Finished [dig len funs]) @@ -226,7 +226,7 @@ run _ B0 t@(Suspend _ _) = t run gi (fz :< EvalPorts valz rem) (Use v) = evalPorts gi fz (valz :< v) rem run gi (fz :< DoSplices hugr nid rest) (Use v) = let (KernelV sub_hugr) = v - hugr' = execState (HG.splice_prepend nid sub_hugr) hugr + hugr' = execState (HG.splicePrepend nid sub_hugr) hugr in evalSplices gi fz hugr' rest run gi (fz :< CallWith inputs) (Use (ThunkV th)) = runThunk gi (B0 :< ReturnTo fz) th inputs diff --git a/brat/Brat/Parser.hs b/brat/Brat/Parser.hs index 8214e596..a0ed28f7 100644 --- a/brat/Brat/Parser.hs +++ b/brat/Brat/Parser.hs @@ -783,7 +783,7 @@ declSignature = try nDecl <|> vDecl where kernel :: Parser (WC (CType' (TypeRowElem (WC Flat)))) kernel = do - WC startFC ins <- inBracketsFC Paren $ flatIO' + WC startFC ins <- inBracketsFC Paren flatIO' match Lolly WC endFC outs <- spanningFC =<< flatIO' pure (WC (spanFC startFC endFC) (ins :-> outs)) diff --git a/brat/Brat/Syntax/Raw.hs b/brat/Brat/Syntax/Raw.hs index f7115982..14dad9be 100644 --- a/brat/Brat/Syntax/Raw.hs +++ b/brat/Brat/Syntax/Raw.hs @@ -233,7 +233,7 @@ instance (Kindable k) => Desugarable (Raw d k) where instance Desugarable (CType' (TypeRowElem RawVType)) where type Desugared (CType' (TypeRowElem RawVType)) = CType' (TypeRowElem (Term Chk Noun)) desugar' :: CType' (TypeRowElem RawVType) -> Desugar (CType' (TypeRowElem (Term Chk Noun))) - desugar' cty = traverse desugar' cty + desugar' = traverse desugar' isConOrAlias :: QualName -> Desugar Bool isConOrAlias c = do diff --git a/brat/Brat/Unelaborator.hs b/brat/Brat/Unelaborator.hs index a4c9368e..7e06bce3 100644 --- a/brat/Brat/Unelaborator.hs +++ b/brat/Brat/Unelaborator.hs @@ -34,9 +34,9 @@ unelab dy ky (top :-: bot) = case ky of unelab dy ky (f :$: s) = FApp (unelab dy KVerby <$> f) (unelab Chky ky <$> s) unelab dy _ (Lambda (abs,rhs) cs) = FLambda ((abs, unelab dy Nouny <$> rhs) :| (second (fmap (unelab Chky Nouny)) <$> cs)) unelab _ _ (Con c args) = FCon c (unelab Chky Nouny <$> args) -unelab _ _ (C (ss :-> ts)) = FFn ((unelabRo ss) +unelab _ _ (C (ss :-> ts)) = FFn (unelabRo ss :-> - (unelabRo ts) + unelabRo ts ) unelab _ _ (K (ss :-> ts)) = FKernel (unelabKernRo ss :-> unelabKernRo ts) unelab _ _ Identity = FIdentity @@ -47,5 +47,5 @@ unelab _ _ FanOut = FFanOut unelabKernRo :: [TypeRowElem (Term Chk Noun)] -> [TypeRowElem (WC Flat)] unelabKernRo = fmap (fmap (dummyFC . unelab Chky Nouny)) -unelabRo :: [(TypeRowElem (KindOr (Term Chk Noun)))] -> [TypeRowElem (WC (KindOr Flat))] +unelabRo :: [TypeRowElem (KindOr (Term Chk Noun))] -> [TypeRowElem (WC (KindOr Flat))] unelabRo = fmap (fmap (dummyFC . fmap (unelab Chky Nouny))) diff --git a/brat/Control/Monad/Freer.hs b/brat/Control/Monad/Freer.hs index ed8b7455..a94dc116 100644 --- a/brat/Control/Monad/Freer.hs +++ b/brat/Control/Monad/Freer.hs @@ -23,7 +23,7 @@ updateEnd (News m) e = case M.lookup e m of -- The RHS of the operation is the newer news -- Invariant: The domains of these Newses are disjoint instance Semigroup News where - (News m1) <> n2@(News m2) = News (m2 `M.union` (M.map (/// n2) m1)) + (News m1) <> n2@(News m2) = News (m2 `M.union` M.map (/// n2) m1) instance Monoid News where mempty = News M.empty @@ -86,7 +86,7 @@ instance Applicative (Free sig) where -- Make progress on the left Ret f <*> ma = fmap f ma Req sig k <*> ma = Req sig ((<*> ma) . k) - Define lbl e v k1 <*> ma = Define lbl e v $ \n -> (k1 n) <*> (ma /// n) + Define lbl e v k1 <*> ma = Define lbl e v $ \n -> k1 n <*> (ma /// n) -- What happens when Yield is on the left y <*> Ret v = fmap ($ v) y diff --git a/brat/Data/HugrGraph.hs b/brat/Data/HugrGraph.hs index 5c76f531..055f6915 100644 --- a/brat/Data/HugrGraph.hs +++ b/brat/Data/HugrGraph.hs @@ -7,8 +7,8 @@ module Data.HugrGraph(NodeId, setFirstChildren, setOp, getParent, getOp, addEdge, addOrderEdge, - splice, splice_new, splice_prepend, inlineDFG, - serialize, to_json + splice, spliceNew, splicePrepend, inlineDFG, + serialize, toJson ) where import Brat.Naming (Namespace, Name(..), fresh) @@ -33,7 +33,7 @@ getRoot :: HugrGraph n -> n getRoot HugrGraph {root} = root getNodes :: HugrGraph n -> [n] -getNodes HugrGraph {parents, root} = root:(M.keys parents) +getNodes HugrGraph {parents, root} = root:M.keys parents data HugrGraph n = HugrGraph { root :: n, @@ -88,9 +88,9 @@ addEdge (src@(Port s o), tgt@(Port t i)) = state $ \h@HugrGraph {..} -> edges_out = addToMap s (o, tgt) edges_out id, edges_in = addToMap t (src, i) edges_in no_other_inedge } - (Nothing, Just _) -> error $ "addEdge source not present" - (Just _, Nothing) -> error $ "addEdge Target not present" - _ -> error $ "addEdge nodes not present" + (Nothing, Just _) -> error "addEdge source not present" + (Just _, Nothing) -> error "addEdge Target not present" + _ -> error "addEdge nodes not present" where addToMap :: Ord k => k -> v -> M.Map k [v] -> ([v] -> [v]) -> M.Map k [v] addToMap k v m chk = M.alter (Just . (v:) . maybe [] chk) k m @@ -119,7 +119,7 @@ getOp HugrGraph {nodes} n = nodes M.! n -- We expect the new Hugr to be DFG-rooted with the same signature as the hole -- being replaced, although this is not enforced. splice :: forall m n. (Ord n, Ord m) => n -> HugrGraph m -> (m -> n) -> State (HugrGraph n) () -splice hole add non_root_k = modify $ \host -> case (M.lookup hole (nodes host) >>= isHole) of +splice hole add non_root_k = modify $ \host -> case M.lookup hole (nodes host) >>= isHole of Just (_, sig) -> case M.lookup (root add) (nodes add) of -- We could inline the DFG here, which could be done more efficiently (iterating through -- nodes of `add` but not the host), but for now we just splice in the DFG in place @@ -152,8 +152,8 @@ splice hole add non_root_k = modify $ \host -> case (M.lookup hole (nodes host) -- Replace the specified hole of the host Hugr (in the State monad), with a new Hugr, -- where both have NodeId keys, by prefixing the new Hugr's keys with the NodeId of -- the hole -splice_prepend :: NodeId -> HugrGraph NodeId -> State (HugrGraph NodeId) () -splice_prepend hole add = splice hole add (keyMap M.!) +splicePrepend :: NodeId -> HugrGraph NodeId -> State (HugrGraph NodeId) () +splicePrepend hole add = splice hole add (keyMap M.!) where prefixRoot :: NodeId -> NodeId prefixRoot (NodeId (MkName ids)) = let NodeId (MkName rs) = hole in NodeId $ MkName (rs ++ ids) @@ -166,8 +166,8 @@ splice_prepend hole add = splice hole add (keyMap M.!) -- Replace the specified hole of a host Hugr (in the State monad, with NodeId keys) with -- a new Hugr of any key type, using a Namespace to generate a fresh NodeId for each node -- of the new Hugr -splice_new :: forall n. (Ord n, Show n) => NodeId -> HugrGraph n -> State (HugrGraph NodeId, Namespace) () -splice_new hole add = modify $ \(host, ns) -> +spliceNew :: forall n. (Ord n, Show n) => NodeId -> HugrGraph n -> State (HugrGraph NodeId, Namespace) () +spliceNew hole add = modify $ \(host, ns) -> let (ns_out, keyMap) = foldr newMapping (ns, M.empty) (M.keys (parents add)) newMapping :: n -> (Namespace, M.Map n NodeId) -> (Namespace, M.Map n NodeId) @@ -198,7 +198,7 @@ inlineDFG dfg = get >>= \h -> case M.lookup dfg (nodes h) of -- or combine with splicing so we only iterate through the inserted -- hugr (which we do anyway) rather than the host. parents = M.fromList [(n, if p==dfg then newp else p) - | (n,p) <- M.assocs (parents h), not (elem n to_remove)] + | (n,p) <- M.assocs (parents h), n `notElem` to_remove] } other -> error $ "Expected DFG, found " ++ show other where @@ -220,7 +220,7 @@ takeInEdges tgt = do removeFromOutList [] _ = error "Out-edge not found" removeFromOutList (e:es) e' | e == e' = es removeFromOutList ((outport, _):_) (outport', _) | outport == outport' = error "Wrong out-edge" - removeFromOutList (e:es) r = e:(removeFromOutList es r) + removeFromOutList (e:es) r = e:removeFromOutList es r takeOutEdges :: forall n. Ord n => n -> State (HugrGraph n) [(Int, PortId n)] takeOutEdges src = do @@ -238,10 +238,10 @@ takeOutEdges src = do removeFromInList [] _ = error "In-edge not found" removeFromInList (e:es) e' | e==e' = es removeFromInList ((_, inport):_) (_,inport') | inport == inport' = error "Wrong in-edge" - removeFromInList (e:es) r = e:(removeFromInList es r) + removeFromInList (e:es) r = e:removeFromInList es r -to_json :: HugrGraph NodeId -> BS.ByteString -to_json = encode . serialize +toJson :: HugrGraph NodeId -> BS.ByteString +toJson = encode . serialize serialize :: forall n. (Ord n, Show n) => HugrGraph n -> Hugr Int serialize hugr = renameAndSort (execState (for_ orderEdges addOrderEdge) hugr) @@ -251,7 +251,7 @@ serialize hugr = renameAndSort (execState (for_ orderEdges addOrderEdge) hugr) -- Nonlocal edges (from a node to another which is a *descendant* of a sibling of the source) -- require an extra order edge from the source to the sibling that is ancestor of the target let interEdges = [(n1, n2) | (Port n1 _, Port n2 _) <- edgeList hugr, - (parentOf n1 /= parentOf n2), + parentOf n1 /= parentOf n2, requiresOrderEdge n1, requiresOrderEdge n2] in track ("interEdges: " ++ show interEdges) (walkUp <$> interEdges) @@ -277,7 +277,7 @@ type StackAndIndices n = (Bwd (n, HugrOp) -- node is index, this is (parent, op) renameAndSort :: forall n. Ord n => HugrGraph n -> Hugr Int renameAndSort hugr@(HugrGraph {root, first_children=fc, nodes, parents}) = Hugr ( - (first transNode) <$> (fst nodeStackAndIndices) <>> [], + first transNode <$> fst nodeStackAndIndices <>> [], [(Port (transNode s) o, Port (transNode t) i) | (Port s o, Port t i) <- edgeList hugr] ) where first_children k = M.findWithDefault [] k fc @@ -298,4 +298,4 @@ renameAndSort hugr@(HugrGraph {root, first_children=fc, nodes, parents}) = Hugr in foldl addNode with_n (first_children n) transNode :: n -> Int - transNode = ((snd nodeStackAndIndices) M.!) + transNode = (snd nodeStackAndIndices M.!) diff --git a/brat/app/Main.hs b/brat/app/Main.hs index 3acaa413..8336572c 100644 --- a/brat/app/Main.hs +++ b/brat/app/Main.hs @@ -2,7 +2,7 @@ import Brat.Compiler import Brat.Machine (runInterpreter) import qualified Data.ByteString.Lazy as BS (putStr) -import Data.HugrGraph (to_json) +import Data.HugrGraph (toJson) import Data.Text.Lazy.IO (putStr) import Control.Monad (when) @@ -54,5 +54,5 @@ main = do else do result <- runInterpreter libDirs file runFunc case result of - Right hugr -> BS.putStr (to_json hugr) + Right hugr -> BS.putStr (toJson hugr) Left s -> putStr s diff --git a/brat/test/Test/Compile/Hugr.hs b/brat/test/Test/Compile/Hugr.hs index 1551f85c..03056b1c 100644 --- a/brat/test/Test/Compile/Hugr.hs +++ b/brat/test/Test/Compile/Hugr.hs @@ -9,7 +9,7 @@ import Test.Tasty import Test.Tasty.HUnit import Data.Hugr (isHole) -import Data.HugrGraph (to_json, getOp, HugrGraph, getNodes) +import Data.HugrGraph (toJson, getOp, HugrGraph, getNodes) import Data.List (sort) import Data.Maybe (isJust) import Brat.Compiler (compileFile, CompilingHoles(..)) @@ -21,15 +21,15 @@ compileToOutput :: String -> FilePath -> TestTree compileToOutput name file = testCaseInfo name $ do createDirectoryIfMissing False outputDir compileFile [] file >>= \case - Right hs -> mconcat <$> (forM (M.toList hs) $ \(boxName, (hugr, holes)) -> do + Right hs -> mconcat <$> forM (M.toList hs) (\(boxName, (hugr, holes)) -> do sort (getHoles hugr) @?= sort holes -- ignore splices for now - let outFile = outputDir replaceExtension (takeFileName file) ((show boxName) ++ ".json") + let outFile = outputDir replaceExtension (takeFileName file) (show boxName ++ ".json") -- lots of fun with lazy and even strict bytestrings -- returning many bytes before evaluation has completed - BS.writeFile outFile $! (BS.toStrict $ to_json hugr) + BS.writeFile outFile $! BS.toStrict (toJson hugr) pure $ "Written to " ++ outFile ++ " pending validation\n") Left (CompilingHoles _) -> pure "Skipped as contains holes" getHoles :: Ord a => HugrGraph a -> [a] -getHoles hg = [n | n <- getNodes hg, isJust (isHole $ getOp hg n)] \ No newline at end of file +getHoles hg = [n | n <- getNodes hg, isJust (isHole $ getOp hg n)] diff --git a/brat/test/Test/Examples.hs b/brat/test/Test/Examples.hs index 41c547ff..bfc5e50c 100644 --- a/brat/test/Test/Examples.hs +++ b/brat/test/Test/Examples.hs @@ -4,7 +4,7 @@ import Test.Checking (parseAndCheckNamed) import Test.Compile.Hugr (compileToOutput, getHoles) import Brat.Load (parseFile) import Brat.Machine (runInterpreter) -import Data.HugrGraph (to_json) +import Data.HugrGraph (toJson) import qualified Data.ByteString as BS import Data.Char (isAlphaNum) @@ -42,9 +42,9 @@ getExamplesTests = do Left err -> assertFailure (show err) Right _ -> return () -- OK checkTest = parseAndCheckNamed "checking" [] path - in if isPrefixOf "--!xfail-parsing" cts then + in if "--!xfail-parsing" `isPrefixOf` cts then testGroup (show path) [expectFail parseTest] - else if isPrefixOf "--!xfail-checking" cts then + else if "--!xfail-checking" `isPrefixOf` cts then testGroup (show path) [parseTest, expectFail checkTest] else let interpreterTests = T.breakOnAll execTestPrefix (T.pack cts) <&> \(_, start) -> @@ -56,7 +56,7 @@ getExamplesTests = do -- "-xfail " and the (un-)expected result -- "-hugr\n" (checks no splices, outputs hugr for validation) restLine = fromJust $ T.stripPrefix execTestPrefix testLine - in if (T.pack "-hugr") == restLine then testCaseInfo func_name $ do + in if T.pack "-hugr" == restLine then testCaseInfo func_name $ do let outFile = outputDir dropExtension (takeFileName path) ++ "_" ++ func_name <.> "json" -- this completely recompiles the file for each test, which is pretty bad hugr <- runInterpreter [] path func_name >>= \case @@ -65,7 +65,7 @@ getExamplesTests = do getHoles hugr @?= [] -- output the hugr for validation createDirectoryIfMissing False outputDir - BS.writeFile outFile $! (BS.toStrict $ to_json hugr) + BS.writeFile outFile $! BS.toStrict (toJson hugr) pure $ "Written hugr to " ++ outFile ++ " pending validation" else let (is_xfail, eOut) = case T.stripPrefix (T.pack "-xfail ") restLine of @@ -79,7 +79,7 @@ getExamplesTests = do Left t -> T.unpack t @?= expectedOutput Right _ -> assertFailure $ "Expected output: '" ++ expectedOutput ++ "' but got a hugr!" compileTest = compileToOutput "compilation" path - checkAndCompile = if isPrefixOf "--!xfail-compilation" cts + checkAndCompile = if "--!xfail-compilation" `isPrefixOf` cts then [checkTest, expectFail compileTest] else [compileTest] in case interpreterTests of [] -> testGroup (show path) checkAndCompile diff --git a/brat/test/Test/HugrGraph.hs b/brat/test/Test/HugrGraph.hs index 7e4ef08e..67f643df 100644 --- a/brat/test/Test/HugrGraph.hs +++ b/brat/test/Test/HugrGraph.hs @@ -4,9 +4,9 @@ import Brat.Naming as N import Data.HugrGraph as H import Data.Hugr -import Control.Monad.State (State, execState, get, runState, modify, state) +import Control.Monad.State (State, execState, gets, runState, modify, state) import Data.Aeson (encode) -import Data.Functor ((<&>)) +import Data.Bifunctor (first) import Data.Maybe (isJust, isNothing) import Data.List (find) import qualified Data.ByteString.Lazy as BS @@ -21,7 +21,7 @@ outputDir = prefix "output" addNode :: String -> NodeId -> HugrOp -> State (HugrGraph NodeId, Namespace) NodeId addNode nam parent op = do name <- H.freshNode parent nam - modify $ \(h, ns) -> (execState (H.setOp name op) h, ns) + modify (first (execState (H.setOp name op))) pure name getSpliceTests :: IO TestTree @@ -36,8 +36,8 @@ testSplice inline prepend = testCaseInfo name $ do BS.writeFile (outPrefix ++ "_host.json") (encode $ H.serialize h) BS.writeFile (outPrefix ++ "_insertee.json") (encode $ H.serialize dfgHugr) let spliced = if prepend - then execState (H.splice_prepend holeId dfgHugr) h - else fst $ execState (H.splice_new holeId dfgHugr) (h, ns) + then execState (H.splicePrepend holeId dfgHugr) h + else fst $ execState (H.spliceNew holeId dfgHugr) (h, ns) let resHugr@(Hugr (ns, _)) = H.serialize $ if inline then execState (inlineDFG holeId) spliced else spliced let outFile = outPrefix ++ "_result.json" @@ -49,10 +49,10 @@ testSplice inline prepend = testCaseInfo name $ do name = (if inline then "inline" else "noinline") ++ (if prepend then "_prepend" else "_new") host :: (NodeId, (HugrGraph NodeId, Namespace)) host = flip runState (runState (H.new "root" rootDefn) N.root) $ do - root <- get <&> H.getRoot . fst + root <- gets (H.getRoot . fst) input <- addNode "inp" root (OpIn (InputNode tys [])) output <- addNode "out" root (OpOut (OutputNode tys [])) - jh $setFirstChildren root [input, output] + jh $ setFirstChildren root [input, output] hole <- addNode "hole" root (OpCustom $ holeOp 0 tq_ty) jh $ H.addEdge (Port input 0, Port hole 0) jh $ H.addEdge (Port input 1, Port hole 1) @@ -63,7 +63,7 @@ testSplice inline prepend = testCaseInfo name $ do dfgHugr = let (initHugr, ns) = runState (H.new "root" rootDfg) N.root in fst $ flip execState (initHugr, ns) $ do - root <- get <&> H.getRoot . fst + root <- gets (H.getRoot . fst) input <- addNode "inp" root (OpIn (InputNode tys [])) output <- addNode "out" root (OpOut (OutputNode tys [])) jh $ setFirstChildren root [input, output] @@ -80,4 +80,4 @@ testSplice inline prepend = testCaseInfo name $ do jh :: State (HugrGraph NodeId) a -> State (HugrGraph NodeId, Namespace) a jh action = state $ \ (h, ns) -> - let (a, h') = runState action h in (a, (h', ns)) \ No newline at end of file + let (a, h') = runState action h in (a, (h', ns)) diff --git a/brat/test/Test/Util.hs b/brat/test/Test/Util.hs index 88981314..bacee0d6 100644 --- a/brat/test/Test/Util.hs +++ b/brat/test/Test/Util.hs @@ -24,7 +24,7 @@ assertCheckingFail :: Show a => String -> Checking a -> Assertion assertCheckingFail needle m = case runEmpty $ localFC (FC (Pos 0 0) (Pos 0 0)) m of Right res -> assertFailure ("Computation produced result " ++ show res ++ " when should have Thrown") Left err -> let shown = showError err in - if isInfixOf needle shown then pure () else assertFailure ("Unexpected error " ++ shown) + if needle `isInfixOf` shown then pure () else assertFailure ("Unexpected error " ++ shown) expectFailForPaths :: [FilePath] -> (FilePath -> TestTree) -> [FilePath] -> [TestTree] expectFailForPaths xf makeTest paths = if S.null not_found then tests else