mirror of
https://github.com/unisonweb/unison.git
synced 2024-11-14 07:51:12 +03:00
Merge pull request #1380 from unisonweb/topic/trailing-whitespace
remove all trailing whitespace
This commit is contained in:
commit
ea39f957b3
@ -167,8 +167,8 @@ transitiveDependencies code seen0 rid = if Set.member rid seen0
|
||||
in CL.getTerm code rid >>= \case
|
||||
Just t ->
|
||||
foldM (transitiveDependencies code) seen (getIds $ Term.dependencies t)
|
||||
Nothing ->
|
||||
CL.getTypeDeclaration code rid >>= \case
|
||||
Nothing ->
|
||||
CL.getTypeDeclaration code rid >>= \case
|
||||
Nothing -> pure seen
|
||||
Just (Left ed) -> foldM (transitiveDependencies code)
|
||||
seen
|
||||
|
@ -32,9 +32,9 @@ fromNames0 names0 = Branch.one $ addFromNames0 names0 Branch.empty0
|
||||
|
||||
-- can produce a pure value because there's no history to traverse
|
||||
hashesFromNames0 :: Monad m => Names0 -> Map Branch.Hash (Branch m)
|
||||
hashesFromNames0 = deepHashes . fromNames0 where
|
||||
hashesFromNames0 = deepHashes . fromNames0 where
|
||||
deepHashes :: Branch m -> Map Branch.Hash (Branch m)
|
||||
deepHashes b = Map.singleton (Branch.headHash b) b
|
||||
deepHashes b = Map.singleton (Branch.headHash b) b
|
||||
<> (foldMap deepHashes . view Branch.children . Branch.head) b
|
||||
|
||||
addFromNames0 :: Monad m => Names0 -> Branch0 m -> Branch0 m
|
||||
|
@ -17,7 +17,7 @@ import Unison.Codebase.Editor.RemoteRepo
|
||||
|
||||
import qualified Unison.Builtin as B
|
||||
|
||||
import qualified Crypto.Random as Random
|
||||
import qualified Crypto.Random as Random
|
||||
import Control.Monad.Except ( runExceptT )
|
||||
import qualified Data.Configurator as Config
|
||||
import Data.Configurator.Types ( Config )
|
||||
@ -108,7 +108,7 @@ commandLine config awaitInput setBranchRef rt notifyUser notifyNumbered loadSour
|
||||
Free.foldWithIndex go
|
||||
where
|
||||
go :: forall x . Int -> Command IO i v x -> IO x
|
||||
go i x = case x of
|
||||
go i x = case x of
|
||||
-- Wait until we get either user input or a unison file update
|
||||
Eval m -> m
|
||||
Input -> awaitInput
|
||||
@ -171,10 +171,10 @@ commandLine config awaitInput setBranchRef rt notifyUser notifyNumbered loadSour
|
||||
-- all builtin and derived term references & type constructors
|
||||
TermReferentsByShortHash sh -> do
|
||||
fromCodebase <- Codebase.termReferentsByPrefix codebase sh
|
||||
let fromBuiltins = Set.map Referent.Ref
|
||||
let fromBuiltins = Set.map Referent.Ref
|
||||
. Set.filter (\r -> sh == Reference.toShortHash r)
|
||||
$ B.intrinsicTermReferences
|
||||
pure (fromBuiltins <> Set.map (fmap Reference.DerivedId) fromCodebase)
|
||||
pure (fromBuiltins <> Set.map (fmap Reference.DerivedId) fromCodebase)
|
||||
BranchHashLength -> Codebase.branchHashLength codebase
|
||||
BranchHashesByPrefix h -> Codebase.branchHashesByPrefix codebase h
|
||||
LoadRemoteShortBranch GitRepo{..} sbh -> do
|
||||
|
@ -215,15 +215,15 @@ loop = do
|
||||
getHQ'Terms p = BranchUtil.getTerm (resolveSplit' p) root0
|
||||
getHQ'Types :: Path.HQSplit' -> Set Reference
|
||||
getHQ'Types p = BranchUtil.getType (resolveSplit' p) root0
|
||||
getHQTerms :: HQ.HashQualified -> Action' m v (Set Referent)
|
||||
getHQTerms :: HQ.HashQualified -> Action' m v (Set Referent)
|
||||
getHQTerms hq = case hq of
|
||||
HQ.NameOnly n -> let
|
||||
-- absolute-ify the name, then lookup in deepTerms of root
|
||||
path :: Path.Path'
|
||||
path :: Path.Path'
|
||||
path = Path.fromName' n
|
||||
Path.Absolute absPath = resolveToAbsolute path
|
||||
in pure $ R.lookupRan (Path.toName absPath) (Branch.deepTerms root0)
|
||||
HQ.HashOnly sh -> hashOnly sh
|
||||
in pure $ R.lookupRan (Path.toName absPath) (Branch.deepTerms root0)
|
||||
HQ.HashOnly sh -> hashOnly sh
|
||||
HQ.HashQualified _ sh -> hashOnly sh
|
||||
where
|
||||
hashOnly sh = eval $ TermReferentsByShortHash sh
|
||||
@ -505,7 +505,7 @@ loop = do
|
||||
where
|
||||
go types src = op (src, mdType, mdValue) types
|
||||
in over Branch.terms tmUpdates . over Branch.types tyUpdates $ b0
|
||||
(_srcle, _srclt, mdValues) ->
|
||||
(_srcle, _srclt, mdValues) ->
|
||||
respond $ MetadataAmbiguous ppe mdValues
|
||||
delete
|
||||
:: (Path.HQSplit' -> Set Referent) -- compute matching terms
|
||||
|
@ -107,7 +107,7 @@ data Input
|
||||
| TestI Bool Bool -- TestI showSuccesses showFailures
|
||||
-- metadata
|
||||
-- `link metadata definitions` (adds metadata to all of `definitions`)
|
||||
| LinkI HQ.HashQualified [Path.HQSplit']
|
||||
| LinkI HQ.HashQualified [Path.HQSplit']
|
||||
-- `unlink metadata definitions` (removes metadata from all of `definitions`)
|
||||
| UnlinkI HQ.HashQualified [Path.HQSplit']
|
||||
-- links from <type>
|
||||
|
@ -329,7 +329,7 @@ toOutput typeOf declOrBuiltin hqLen names1 names2 ppe
|
||||
where
|
||||
fillMetadata :: Traversable t => PPE.PrettyPrintEnv -> t Metadata.Value -> m (t (MetadataDisplay v a))
|
||||
fillMetadata ppe = traverse $ -- metadata values are all terms
|
||||
\(Referent.Ref -> mdRef) ->
|
||||
\(Referent.Ref -> mdRef) ->
|
||||
let name = PPE.termName ppe mdRef
|
||||
in (name, mdRef, ) <$> typeOf mdRef
|
||||
getMetadata :: Ord r => r -> Name -> R3.Relation3 r Name Metadata.Value -> Set Metadata.Value
|
||||
|
@ -49,9 +49,9 @@ delete (a, ty, v) s = let
|
||||
-- if (ty,v) is the last metadata of type ty
|
||||
-- we also delete (a, ty) from the d2 index
|
||||
metadataByType = List.multimap (toList (R.lookupDom a (Star3.d3 s)))
|
||||
in
|
||||
in
|
||||
case Map.lookup ty metadataByType of
|
||||
Just vs | all (== v) vs -> Star3.deleteD2 (a, ty) s'
|
||||
Just vs | all (== v) vs -> Star3.deleteD2 (a, ty) s'
|
||||
_ -> s'
|
||||
|
||||
-- parallel composition - commutative and associative
|
||||
|
@ -20,11 +20,11 @@ fromText t =
|
||||
case Text.words t of
|
||||
(Hash.fromBase32Hex -> Just old) : (Hash.fromBase32Hex -> Just new) : (Text.unwords -> reason) ->
|
||||
Just $ Entry (Causal.RawHash old) (Causal.RawHash new) reason
|
||||
_ -> Nothing
|
||||
_ -> Nothing
|
||||
|
||||
|
||||
|
||||
toText :: Entry -> Text
|
||||
toText (Entry old new reason) =
|
||||
toText (Entry old new reason) =
|
||||
Text.unwords [ Hash.base32Hex . Causal.unRawHash $ old
|
||||
, Hash.base32Hex . Causal.unRawHash $ new
|
||||
, reason ]
|
||||
, reason ]
|
||||
|
@ -259,7 +259,7 @@ run dir configFile stanzas codebase = do
|
||||
loop state = do
|
||||
writeIORef pathRef (view HandleInput.currentPath state)
|
||||
let free = runStateT (runMaybeT HandleInput.loop) state
|
||||
rng i = pure $ Random.drgNewSeed (Random.seedFromInteger (fromIntegral i))
|
||||
rng i = pure $ Random.drgNewSeed (Random.seedFromInteger (fromIntegral i))
|
||||
(o, state') <- HandleCommand.commandLine config awaitInput
|
||||
(const $ pure ())
|
||||
runtime
|
||||
|
@ -56,9 +56,9 @@ watchDirectory' d = do
|
||||
-- janky: used to store the cancellation action returned
|
||||
-- by `watchDir`, which is created asynchronously
|
||||
cleanupRef <- newEmptyMVar
|
||||
-- we don't like FSNotify's debouncing (it seems to drop later events)
|
||||
-- we don't like FSNotify's debouncing (it seems to drop later events)
|
||||
-- so we will be doing our own instead
|
||||
let config = FSNotify.defaultConfig { FSNotify.confDebounce = FSNotify.NoDebounce }
|
||||
let config = FSNotify.defaultConfig { FSNotify.confDebounce = FSNotify.NoDebounce }
|
||||
cancel <- forkIO $ withRunInIO $ \inIO ->
|
||||
FSNotify.withManagerConf config $ \mgr -> do
|
||||
cancelInner <- FSNotify.watchDir mgr d (const True) (inIO . handler) <|> (pure (pure ()))
|
||||
@ -123,7 +123,7 @@ watchDirectory dir allow = do
|
||||
ctx <- UnliftIO.askUnliftIO
|
||||
-- We spawn a separate thread to siphon the file change events
|
||||
-- into a queue, which can be debounced using `collectUntilPause`
|
||||
enqueuer <- liftIO . forkIO $ do
|
||||
enqueuer <- liftIO . forkIO $ do
|
||||
takeMVar gate -- wait until gate open before starting
|
||||
forever $ do
|
||||
event@(file, _) <- UnliftIO.unliftIO ctx watcher
|
||||
@ -141,9 +141,9 @@ watchDirectory dir allow = do
|
||||
events <- collectUntilPause queue 50000
|
||||
-- traceM $ "Collected file change events" <> show events
|
||||
case events of
|
||||
[] -> pure Nothing
|
||||
-- we pick the last of the events within the 50ms window
|
||||
-- TODO: consider enqueing other events if there are
|
||||
[] -> pure Nothing
|
||||
-- we pick the last of the events within the 50ms window
|
||||
-- TODO: consider enqueing other events if there are
|
||||
-- multiple events for different files
|
||||
_ -> uncurry process $ last events
|
||||
((file, t):rest) -> do
|
||||
|
@ -23,7 +23,7 @@ import qualified Unison.DataDeclaration as DD
|
||||
import qualified Unison.Hash as Hash
|
||||
import Unison.Reference (Reference, pattern Builtin, pattern Derived)
|
||||
import qualified Unison.Referent as Referent
|
||||
import qualified Unison.ConstructorType as ConstructorType
|
||||
import qualified Unison.ConstructorType as ConstructorType
|
||||
import Unison.Term
|
||||
import Unison.UnisonFile (UnisonFile, pattern UnisonFile)
|
||||
import qualified Unison.UnisonFile as UF
|
||||
@ -294,10 +294,10 @@ serializeReferent :: MonadPut m => Referent.Referent -> m ()
|
||||
serializeReferent r = case r of
|
||||
Referent.Ref r -> putWord8 0 *> serializeReference r
|
||||
Referent.Con r cid ct -> do
|
||||
putWord8 1
|
||||
serializeReference r
|
||||
putWord8 1
|
||||
serializeReference r
|
||||
putLength cid
|
||||
serializeConstructorType ct
|
||||
serializeConstructorType ct
|
||||
|
||||
serializeConstructorType :: MonadPut m => ConstructorType.ConstructorType -> m ()
|
||||
serializeConstructorType ct = case ct of
|
||||
|
@ -1121,7 +1121,7 @@ link = InputPattern
|
||||
(\case
|
||||
md : defs -> first fromString $ do
|
||||
md <- case HQ.fromString md of
|
||||
Nothing -> Left "Invalid hash qualified identifier for metadata."
|
||||
Nothing -> Left "Invalid hash qualified identifier for metadata."
|
||||
Just hq -> pure hq
|
||||
defs <- traverse Path.parseHQSplit' defs
|
||||
Right $ Input.LinkI md defs
|
||||
@ -1160,10 +1160,10 @@ unlink = InputPattern
|
||||
(\case
|
||||
md : defs -> first fromString $ do
|
||||
md <- case HQ.fromString md of
|
||||
Nothing -> Left "Invalid hash qualified identifier for metadata."
|
||||
Nothing -> Left "Invalid hash qualified identifier for metadata."
|
||||
Just hq -> pure hq
|
||||
defs <- traverse Path.parseHQSplit' defs
|
||||
Right $ Input.UnlinkI md defs
|
||||
Right $ Input.UnlinkI md defs
|
||||
_ -> Left (I.help unlink)
|
||||
)
|
||||
|
||||
|
@ -37,7 +37,7 @@ import qualified Data.Text as Text
|
||||
import qualified Data.Text.IO
|
||||
import qualified System.Console.Haskeline as Line
|
||||
import System.IO.Error (isDoesNotExistError)
|
||||
import qualified Crypto.Random as Random
|
||||
import qualified Crypto.Random as Random
|
||||
import qualified Unison.Codebase.Path as Path
|
||||
import qualified Unison.Codebase.Runtime as Runtime
|
||||
import qualified Unison.Codebase as Codebase
|
||||
@ -236,7 +236,7 @@ main dir initialPath configFile initialInputs startRuntime codebase = do
|
||||
loop state = do
|
||||
writeIORef pathRef (view HandleInput.currentPath state)
|
||||
let free = runStateT (runMaybeT HandleInput.loop) state
|
||||
|
||||
|
||||
(o, state') <- HandleCommand.commandLine config awaitInput
|
||||
(writeIORef rootRef)
|
||||
runtime
|
||||
|
@ -326,7 +326,7 @@ notifyUser dir o = case o of
|
||||
P.wrap $ "This might be due to pulling an incomplete"
|
||||
<> "or invalid codebase, or because files inside the codebase"
|
||||
<> "are being deleted external to UCM."
|
||||
]
|
||||
]
|
||||
MetadataAmbiguous _ppe [] -> pure . P.warnCallout .
|
||||
P.wrap $ "Nothing to do. I couldn't find any matching metadata."
|
||||
MetadataAmbiguous ppe refs -> pure . P.warnCallout . P.lines $ [
|
||||
|
@ -40,7 +40,7 @@ prettyDecl
|
||||
-> HashQualified
|
||||
-> DD.Decl v a
|
||||
-> Pretty SyntaxText
|
||||
prettyDecl ppe r hq d = case d of
|
||||
prettyDecl ppe r hq d = case d of
|
||||
Left e -> prettyEffectDecl ppe r hq e
|
||||
Right dd -> prettyDataDecl ppe r hq dd
|
||||
|
||||
@ -182,7 +182,7 @@ prettyDeclOrBuiltinHeader
|
||||
-> DD.DeclOrBuiltin v a
|
||||
-> Pretty SyntaxText
|
||||
prettyDeclOrBuiltinHeader name (DD.Builtin ctype) = case ctype of
|
||||
CT.Data -> fmt S.DataTypeKeyword "builtin type " <> styleHashQualified'' (fmt S.DataType) name
|
||||
CT.Data -> fmt S.DataTypeKeyword "builtin type " <> styleHashQualified'' (fmt S.DataType) name
|
||||
CT.Effect -> fmt S.DataTypeKeyword "builtin ability " <> styleHashQualified'' (fmt S.DataType) name
|
||||
prettyDeclOrBuiltinHeader name (DD.Decl e) = prettyDeclHeader name e
|
||||
|
||||
|
@ -7,7 +7,7 @@ module Unison.Parser where
|
||||
|
||||
import Unison.Prelude
|
||||
|
||||
import qualified Crypto.Random as Random
|
||||
import qualified Crypto.Random as Random
|
||||
import Data.Bytes.Put (runPutS)
|
||||
import Data.Bytes.Serial ( serialize )
|
||||
import Data.Bytes.VarInt ( VarInt(..) )
|
||||
|
@ -90,4 +90,4 @@ hoist
|
||||
:: (Monad f, Monoid notes)
|
||||
=> (forall a. f a -> g a)
|
||||
-> ResultT notes f b -> ResultT notes g b
|
||||
hoist morph = Morph.hoist (Morph.hoist morph)
|
||||
hoist morph = Morph.hoist (Morph.hoist morph)
|
||||
|
@ -56,7 +56,7 @@ typeNamedId s =
|
||||
|
||||
typeNamed :: String -> R.Reference
|
||||
typeNamed = R.DerivedId . typeNamedId
|
||||
|
||||
|
||||
abilityNamedId :: String -> R.Id
|
||||
abilityNamedId s =
|
||||
case Map.lookup (Var.nameds s) (UF.effectDeclarationsId' typecheckedFile) of
|
||||
|
@ -470,8 +470,8 @@ compile0 env bound t =
|
||||
Term.Boolean' n -> Leaf . Val . B $ n
|
||||
Term.Text' n -> Leaf . Val . T $ n
|
||||
Term.Char' n -> Leaf . Val . C $ n
|
||||
Term.TermLink' r -> Leaf . Val . TermLink $ r
|
||||
Term.TypeLink' r -> Leaf . Val . TypeLink $ r
|
||||
Term.TermLink' r -> Leaf . Val . TermLink $ r
|
||||
Term.TypeLink' r -> Leaf . Val . TypeLink $ r
|
||||
Term.And' x y -> And (toZ "and" t x) (go y)
|
||||
Term.LamsNamed' vs body -> Leaf . Val $
|
||||
Lam (length vs)
|
||||
@ -495,7 +495,7 @@ compile0 env bound t =
|
||||
Term.Var' _ -> Leaf $ toZ "var" t t
|
||||
Term.Ref' r -> case toIR env r of
|
||||
Nothing -> error $ reportBug "B8920912182" msg where
|
||||
msg = "The program being compiled referenced this definition " <>
|
||||
msg = "The program being compiled referenced this definition " <>
|
||||
show r <> "\nbut the compilation environment has no compiled form for this reference."
|
||||
Just ir -> ir
|
||||
Term.Sequence' vs -> MakeSequence . toList . fmap (toZ "sequence" t) $ vs
|
||||
|
@ -473,8 +473,8 @@ runtime = Runtime terminate eval
|
||||
Map.empty
|
||||
term <- case Components.minimize' term of
|
||||
Left es -> fail . reportBug "B23784210" $
|
||||
"Term contains duplicate definitions: " <> show (fst <$> es)
|
||||
Right term -> pure term
|
||||
"Term contains duplicate definitions: " <> show (fst <$> es)
|
||||
Right term -> pure term
|
||||
r <- try $ RT.run (handleIO' cenv $ S mmap)
|
||||
cenv
|
||||
(IR.compile cenv $ Term.amap (const ()) term)
|
||||
@ -496,8 +496,8 @@ toTermOrError ppe r = case r of
|
||||
]
|
||||
Right (RT.RError t val) -> do
|
||||
msg <- IR.decompile val
|
||||
let errorType = case t of
|
||||
RT.ErrorTypeTodo -> "builtin.todo"
|
||||
let errorType = case t of
|
||||
RT.ErrorTypeTodo -> "builtin.todo"
|
||||
RT.ErrorTypeBug -> "builtin.bug"
|
||||
pure . Left . P.callout icon . P.lines $ [
|
||||
P.wrap ("I've encountered a call to" <> P.red errorType
|
||||
|
@ -911,9 +911,9 @@ calcImports im tm = (im', render $ getUses result)
|
||||
|> Set.filter (\(k1, _) -> k1 == k1')
|
||||
|> Set.map snd)
|
||||
maxk2s = Map.map maximum k2s
|
||||
err k1 k2 = error $
|
||||
"TermPrinter.longestPrefix not found "
|
||||
<> show (k1,k2)
|
||||
err k1 k2 = error $
|
||||
"TermPrinter.longestPrefix not found "
|
||||
<> show (k1,k2)
|
||||
<> " in " <> show maxk2s
|
||||
in Map.mapWithKey (\k1 k2 -> fromMaybe (err k1 k2) $ Map.lookup (k1, k2) m) maxk2s
|
||||
-- Don't do another `use` for a name for which we've already done one, unless the
|
||||
|
@ -51,4 +51,4 @@ liftTerm :: Ord v => Term v a -> Term' (TypeVar b v) v a
|
||||
liftTerm = Term.vtmap Universal
|
||||
|
||||
lowerTerm :: Ord v => Term' (TypeVar b v) v a -> Term v a
|
||||
lowerTerm = Term.vtmap underlying
|
||||
lowerTerm = Term.vtmap underlying
|
||||
|
@ -162,7 +162,7 @@ getDecl' uf v =
|
||||
-- External type references that appear in the types of the file's terms
|
||||
termSignatureExternalLabeledDependencies
|
||||
:: Ord v => TypecheckedUnisonFile v a -> Set LabeledDependency
|
||||
termSignatureExternalLabeledDependencies
|
||||
termSignatureExternalLabeledDependencies
|
||||
(TypecheckedUnisonFile dataDeclarations' effectDeclarations' _ _ hashTerms) =
|
||||
Set.difference
|
||||
(Set.map LD.typeRef
|
||||
|
@ -39,7 +39,7 @@ hiPurple = style HiPurple
|
||||
hiCyan = style HiCyan
|
||||
hiWhite = style HiWhite
|
||||
bold = style Bold
|
||||
underline = style Underline
|
||||
underline = style Underline
|
||||
|
||||
style :: Color -> ColorText -> ColorText
|
||||
style = annotate
|
||||
|
@ -59,7 +59,7 @@ instance Monad (Free f) where
|
||||
return = Pure
|
||||
Pure a >>= f = f a
|
||||
Bind fx f >>= g = Bind fx (f >=> g)
|
||||
|
||||
|
||||
|
||||
instance Applicative (Free f) where
|
||||
pure = Pure
|
||||
|
@ -21,4 +21,4 @@ test = scope "abt" $ tests [
|
||||
[ scope "first" $ expect (not $ Set.member fresh (ABT.freeVars t1))
|
||||
, scope "second" $ expect (not $ Set.member fresh (ABT.freeVars t2))
|
||||
]
|
||||
]
|
||||
]
|
||||
|
@ -39,4 +39,4 @@ safeChars = Set.fromList $
|
||||
['0'..'9'] ++ ['a'..'z'] ++ ['A'..'Z'] ++ "-._$"
|
||||
|
||||
unsafeChars :: [Char]
|
||||
unsafeChars = toList $ (Set.fromList ['!'..'~'] `Set.difference` safeChars)
|
||||
unsafeChars = toList $ (Set.fromList ['!'..'~'] `Set.difference` safeChars)
|
||||
|
@ -8,7 +8,7 @@ import Unison.Symbol (Symbol)
|
||||
import qualified Unison.Var as Var
|
||||
import qualified Unison.Typechecker as Typechecker
|
||||
|
||||
infixr 1 -->
|
||||
infixr 1 -->
|
||||
|
||||
(-->) :: Ord v => Type v () -> Type v () -> Type v ()
|
||||
(-->) a b = arrow() a b
|
||||
@ -23,8 +23,8 @@ test = scope "type" $ tests [
|
||||
_ -> crash "unArrows (a -> b) did not return a spine of [a,b]"
|
||||
,
|
||||
scope "subtype" $ do
|
||||
let v = Var.named "a"
|
||||
v2 = Var.named "b"
|
||||
let v = Var.named "a"
|
||||
v2 = Var.named "b"
|
||||
vt = var() v
|
||||
vt2 = var() v2
|
||||
x = forall() v (nat() --> effect() [vt, builtin() "eff"] (nat())) :: Type Symbol ()
|
||||
|
@ -1,170 +1,170 @@
|
||||
module Unison.Test.TypePrinter where
|
||||
|
||||
import EasyTest
|
||||
import qualified Data.Map as Map
|
||||
import Unison.TypePrinter
|
||||
import qualified Unison.Builtin
|
||||
import Unison.Util.ColorText (toPlain)
|
||||
import qualified Unison.Util.Pretty as PP
|
||||
import qualified Unison.PrettyPrintEnv as PPE
|
||||
import qualified Unison.Test.Common as Common
|
||||
|
||||
|
||||
-- Test the result of the pretty-printer. Expect the pretty-printer to
|
||||
-- produce output that differs cosmetically from the original code we parsed.
|
||||
-- Check also that re-parsing the pretty-printed code gives us the same ABT.
|
||||
-- (Skip that latter check if rtt is false.)
|
||||
-- Note that this does not verify the position of the PrettyPrint Break elements.
|
||||
tc_diff_rtt :: Bool -> String -> String -> Int -> Test ()
|
||||
tc_diff_rtt rtt s expected width =
|
||||
let input_type = Common.t s
|
||||
get_names = PPE.fromNames Common.hqLength Unison.Builtin.names
|
||||
prettied = fmap toPlain $ PP.syntaxToColor $ prettyRaw get_names Map.empty (-1) input_type
|
||||
actual = if width == 0
|
||||
then PP.renderUnbroken $ prettied
|
||||
else PP.render width $ prettied
|
||||
actual_reparsed = Common.t actual
|
||||
in scope s $ tests [(
|
||||
if actual == expected then ok
|
||||
else do note $ "expected: " ++ show expected
|
||||
note $ "actual : " ++ show actual
|
||||
note $ "expectedS:\n" ++ expected
|
||||
note $ "actualS:\n" ++ actual
|
||||
note $ "show(input) : " ++ show input_type
|
||||
note $ "prettyprint : " ++ show prettied
|
||||
crash "actual != expected"
|
||||
), (
|
||||
if (not rtt) || (input_type == actual_reparsed) then ok
|
||||
else do note $ "round trip test..."
|
||||
note $ "single parse: " ++ show input_type
|
||||
note $ "double parse: " ++ show actual_reparsed
|
||||
note $ "prettyprint : " ++ show prettied
|
||||
crash "single parse != double parse"
|
||||
)]
|
||||
|
||||
-- As above, but do the round-trip test unconditionally.
|
||||
tc_diff :: String -> String -> Test ()
|
||||
tc_diff s expected = tc_diff_rtt True s expected 0
|
||||
|
||||
-- As above, but expect not even cosmetic differences between the input string
|
||||
-- and the pretty-printed version.
|
||||
tc :: String -> Test ()
|
||||
tc s = tc_diff s s
|
||||
|
||||
-- Use renderBroken to render the output to some maximum width.
|
||||
tc_breaks :: String -> Int -> String -> Test ()
|
||||
tc_breaks s width expected = tc_diff_rtt True s expected width
|
||||
|
||||
test :: Test ()
|
||||
test = scope "typeprinter" . tests $
|
||||
[ tc "a -> b"
|
||||
, tc "()"
|
||||
, tc "Pair"
|
||||
, tc "Pair a b"
|
||||
, tc "Pair a a"
|
||||
, tc_diff "((a))" $ "a"
|
||||
, tc "Pair a ()" -- unary tuple
|
||||
, tc "(a, a)"
|
||||
, tc "(a, a, a)"
|
||||
, tc "(a, b, c, d)"
|
||||
, tc "Pair a (Pair a a)"
|
||||
, tc "Pair (Pair a a) a"
|
||||
, tc "{} (Pair a a)"
|
||||
, tc "a ->{} b"
|
||||
, tc "a ->{e1} b"
|
||||
, tc "a ->{e1, e2} b -> c ->{} d"
|
||||
, tc "a ->{e1, e2} b ->{} c -> d"
|
||||
, tc "a -> b -> c ->{} d"
|
||||
, tc "a -> b ->{} c -> d"
|
||||
, tc "{e1, e2} (Pair a a)"
|
||||
, tc "Pair (a -> b) (c -> d)"
|
||||
, tc "Pair a b ->{e1, e2} Pair a b ->{} Pair (a -> b) d -> Pair c d"
|
||||
, tc "[Pair a a]"
|
||||
, tc "'a"
|
||||
, tc "'Pair a a"
|
||||
, tc "a -> 'b"
|
||||
, tc "'(a -> b)"
|
||||
, tc "(a -> b) -> c"
|
||||
, tc "'a -> b"
|
||||
, tc "∀ A. A -> A"
|
||||
, tc "∀ foo.A. foo.A -> foo.A"
|
||||
, tc "∀ A B. A -> B -> (A, B)"
|
||||
, tc "a -> 'b -> c"
|
||||
, tc "a -> (b -> c) -> d"
|
||||
, tc "(a -> b) -> c -> d"
|
||||
, tc "((a -> b) -> c) -> d"
|
||||
, tc "(∀ a. 'a) -> ()"
|
||||
, tc "(∀ a. (∀ b. 'b) -> a) -> ()"
|
||||
, tc_diff "∀ a. 'a" $ "'a"
|
||||
, tc "a -> '(b -> c)"
|
||||
, tc "a -> b -> c -> d"
|
||||
, tc "a -> 'Pair b c"
|
||||
, tc "a -> b -> 'c"
|
||||
, tc "a ->{e} 'b"
|
||||
, tc "a -> '{e} b"
|
||||
, tc "a -> '{e} b -> c"
|
||||
, tc "a -> '{e} b ->{f} c"
|
||||
, tc "a -> '{e} (b -> c)"
|
||||
, tc "a -> '{e} (b ->{f} c)"
|
||||
, tc "a -> 'b"
|
||||
, tc "a -> '('b)"
|
||||
, tc "a -> '('(b -> c))"
|
||||
, tc "a -> '('('(b -> c)))"
|
||||
, tc "a -> '{e} ('('(b -> c)))"
|
||||
, tc "a -> '('{e} ('(b -> c)))"
|
||||
, tc "a -> '('('{e} (b -> c)))"
|
||||
, tc "a -> 'b ->{f} c"
|
||||
, tc "a -> '(b -> c)"
|
||||
, tc "a -> '(b ->{f} c)"
|
||||
, tc "a -> '{e} ('b)"
|
||||
, pending $ tc "a -> '{e} 'b" -- issue #249
|
||||
, pending $ tc "a -> '{e} '{f} b" -- issue #249
|
||||
, tc "a -> '{e} ('b)"
|
||||
, tc_diff "a -> () ->{e} () -> b -> c" $ "a -> '{e} ('(b -> c))"
|
||||
, tc "a -> '{e} ('(b -> c))"
|
||||
, tc_diff "a ->{e} () ->{f} b" $ "a ->{e} '{f} b"
|
||||
, tc "a ->{e} '{f} b"
|
||||
, tc_diff "a -> () ->{e} () ->{f} b" $ "a -> '{e} ('{f} b)"
|
||||
, tc "a -> '{e} ('{f} b)"
|
||||
, tc "a -> '{e} () ->{f} b"
|
||||
, tc "a -> '{e} ('{f} (b -> c))"
|
||||
, tc "a ->{e} '(b -> c)"
|
||||
, tc "a -> '{e} (b -> c)"
|
||||
, tc_diff "a -> () ->{e} () -> b" $ "a -> '{e} ('b)"
|
||||
, tc "'{e} a"
|
||||
, tc "'{e} (a -> b)"
|
||||
, tc "'{e} (a ->{f} b)"
|
||||
, pending $ tc "Pair a '{e} b" -- parser hits unexpected '
|
||||
, tc_diff_rtt False "Pair a ('{e} b)" "Pair a '{e} b" 80 -- no RTT due to the above
|
||||
, tc "'(a -> 'a)"
|
||||
, tc "'()"
|
||||
, tc "'('a)"
|
||||
, pending $ tc "''a" -- issue #249
|
||||
, pending $ tc "'''a" -- issue #249
|
||||
, tc_diff "∀ a . a" $ "a"
|
||||
, tc_diff "∀ a. a" $ "a"
|
||||
, tc_diff "∀ a . 'a" $ "'a"
|
||||
, pending $ tc_diff "∀a . a" $ "a" -- lexer doesn't accept, treats ∀a as one lexeme - feels like it should work
|
||||
, pending $ tc_diff "∀ A . 'A" $ "'A" -- 'unknown parse error' - should this be accepted?
|
||||
|
||||
, tc_diff_rtt False "a -> b -> c -> d" -- hitting 'unexpected Semi' in the reparse
|
||||
"a\n\
|
||||
\-> b\n\
|
||||
\-> c\n\
|
||||
\-> d" 10
|
||||
|
||||
, tc_diff_rtt False "a -> Pair b c -> d" -- ditto, and extra line breaks that seem superfluous in Pair
|
||||
"a\n\
|
||||
\-> Pair b c\n\
|
||||
\-> d" 14
|
||||
|
||||
, tc_diff_rtt False "Pair (forall a. (a -> a -> a)) b" -- as above, and TODO not nesting under Pair
|
||||
"Pair\n\
|
||||
\ (∀ a. a -> a -> a) b" 24
|
||||
|
||||
, tc_diff_rtt False "Pair (forall a. (a -> a -> a)) b" -- as above, and TODO not breaking under forall
|
||||
"Pair\n\
|
||||
\ (∀ a. a -> a -> a)\n\
|
||||
\ b" 21
|
||||
|
||||
]
|
||||
module Unison.Test.TypePrinter where
|
||||
|
||||
import EasyTest
|
||||
import qualified Data.Map as Map
|
||||
import Unison.TypePrinter
|
||||
import qualified Unison.Builtin
|
||||
import Unison.Util.ColorText (toPlain)
|
||||
import qualified Unison.Util.Pretty as PP
|
||||
import qualified Unison.PrettyPrintEnv as PPE
|
||||
import qualified Unison.Test.Common as Common
|
||||
|
||||
|
||||
-- Test the result of the pretty-printer. Expect the pretty-printer to
|
||||
-- produce output that differs cosmetically from the original code we parsed.
|
||||
-- Check also that re-parsing the pretty-printed code gives us the same ABT.
|
||||
-- (Skip that latter check if rtt is false.)
|
||||
-- Note that this does not verify the position of the PrettyPrint Break elements.
|
||||
tc_diff_rtt :: Bool -> String -> String -> Int -> Test ()
|
||||
tc_diff_rtt rtt s expected width =
|
||||
let input_type = Common.t s
|
||||
get_names = PPE.fromNames Common.hqLength Unison.Builtin.names
|
||||
prettied = fmap toPlain $ PP.syntaxToColor $ prettyRaw get_names Map.empty (-1) input_type
|
||||
actual = if width == 0
|
||||
then PP.renderUnbroken $ prettied
|
||||
else PP.render width $ prettied
|
||||
actual_reparsed = Common.t actual
|
||||
in scope s $ tests [(
|
||||
if actual == expected then ok
|
||||
else do note $ "expected: " ++ show expected
|
||||
note $ "actual : " ++ show actual
|
||||
note $ "expectedS:\n" ++ expected
|
||||
note $ "actualS:\n" ++ actual
|
||||
note $ "show(input) : " ++ show input_type
|
||||
note $ "prettyprint : " ++ show prettied
|
||||
crash "actual != expected"
|
||||
), (
|
||||
if (not rtt) || (input_type == actual_reparsed) then ok
|
||||
else do note $ "round trip test..."
|
||||
note $ "single parse: " ++ show input_type
|
||||
note $ "double parse: " ++ show actual_reparsed
|
||||
note $ "prettyprint : " ++ show prettied
|
||||
crash "single parse != double parse"
|
||||
)]
|
||||
|
||||
-- As above, but do the round-trip test unconditionally.
|
||||
tc_diff :: String -> String -> Test ()
|
||||
tc_diff s expected = tc_diff_rtt True s expected 0
|
||||
|
||||
-- As above, but expect not even cosmetic differences between the input string
|
||||
-- and the pretty-printed version.
|
||||
tc :: String -> Test ()
|
||||
tc s = tc_diff s s
|
||||
|
||||
-- Use renderBroken to render the output to some maximum width.
|
||||
tc_breaks :: String -> Int -> String -> Test ()
|
||||
tc_breaks s width expected = tc_diff_rtt True s expected width
|
||||
|
||||
test :: Test ()
|
||||
test = scope "typeprinter" . tests $
|
||||
[ tc "a -> b"
|
||||
, tc "()"
|
||||
, tc "Pair"
|
||||
, tc "Pair a b"
|
||||
, tc "Pair a a"
|
||||
, tc_diff "((a))" $ "a"
|
||||
, tc "Pair a ()" -- unary tuple
|
||||
, tc "(a, a)"
|
||||
, tc "(a, a, a)"
|
||||
, tc "(a, b, c, d)"
|
||||
, tc "Pair a (Pair a a)"
|
||||
, tc "Pair (Pair a a) a"
|
||||
, tc "{} (Pair a a)"
|
||||
, tc "a ->{} b"
|
||||
, tc "a ->{e1} b"
|
||||
, tc "a ->{e1, e2} b -> c ->{} d"
|
||||
, tc "a ->{e1, e2} b ->{} c -> d"
|
||||
, tc "a -> b -> c ->{} d"
|
||||
, tc "a -> b ->{} c -> d"
|
||||
, tc "{e1, e2} (Pair a a)"
|
||||
, tc "Pair (a -> b) (c -> d)"
|
||||
, tc "Pair a b ->{e1, e2} Pair a b ->{} Pair (a -> b) d -> Pair c d"
|
||||
, tc "[Pair a a]"
|
||||
, tc "'a"
|
||||
, tc "'Pair a a"
|
||||
, tc "a -> 'b"
|
||||
, tc "'(a -> b)"
|
||||
, tc "(a -> b) -> c"
|
||||
, tc "'a -> b"
|
||||
, tc "∀ A. A -> A"
|
||||
, tc "∀ foo.A. foo.A -> foo.A"
|
||||
, tc "∀ A B. A -> B -> (A, B)"
|
||||
, tc "a -> 'b -> c"
|
||||
, tc "a -> (b -> c) -> d"
|
||||
, tc "(a -> b) -> c -> d"
|
||||
, tc "((a -> b) -> c) -> d"
|
||||
, tc "(∀ a. 'a) -> ()"
|
||||
, tc "(∀ a. (∀ b. 'b) -> a) -> ()"
|
||||
, tc_diff "∀ a. 'a" $ "'a"
|
||||
, tc "a -> '(b -> c)"
|
||||
, tc "a -> b -> c -> d"
|
||||
, tc "a -> 'Pair b c"
|
||||
, tc "a -> b -> 'c"
|
||||
, tc "a ->{e} 'b"
|
||||
, tc "a -> '{e} b"
|
||||
, tc "a -> '{e} b -> c"
|
||||
, tc "a -> '{e} b ->{f} c"
|
||||
, tc "a -> '{e} (b -> c)"
|
||||
, tc "a -> '{e} (b ->{f} c)"
|
||||
, tc "a -> 'b"
|
||||
, tc "a -> '('b)"
|
||||
, tc "a -> '('(b -> c))"
|
||||
, tc "a -> '('('(b -> c)))"
|
||||
, tc "a -> '{e} ('('(b -> c)))"
|
||||
, tc "a -> '('{e} ('(b -> c)))"
|
||||
, tc "a -> '('('{e} (b -> c)))"
|
||||
, tc "a -> 'b ->{f} c"
|
||||
, tc "a -> '(b -> c)"
|
||||
, tc "a -> '(b ->{f} c)"
|
||||
, tc "a -> '{e} ('b)"
|
||||
, pending $ tc "a -> '{e} 'b" -- issue #249
|
||||
, pending $ tc "a -> '{e} '{f} b" -- issue #249
|
||||
, tc "a -> '{e} ('b)"
|
||||
, tc_diff "a -> () ->{e} () -> b -> c" $ "a -> '{e} ('(b -> c))"
|
||||
, tc "a -> '{e} ('(b -> c))"
|
||||
, tc_diff "a ->{e} () ->{f} b" $ "a ->{e} '{f} b"
|
||||
, tc "a ->{e} '{f} b"
|
||||
, tc_diff "a -> () ->{e} () ->{f} b" $ "a -> '{e} ('{f} b)"
|
||||
, tc "a -> '{e} ('{f} b)"
|
||||
, tc "a -> '{e} () ->{f} b"
|
||||
, tc "a -> '{e} ('{f} (b -> c))"
|
||||
, tc "a ->{e} '(b -> c)"
|
||||
, tc "a -> '{e} (b -> c)"
|
||||
, tc_diff "a -> () ->{e} () -> b" $ "a -> '{e} ('b)"
|
||||
, tc "'{e} a"
|
||||
, tc "'{e} (a -> b)"
|
||||
, tc "'{e} (a ->{f} b)"
|
||||
, pending $ tc "Pair a '{e} b" -- parser hits unexpected '
|
||||
, tc_diff_rtt False "Pair a ('{e} b)" "Pair a '{e} b" 80 -- no RTT due to the above
|
||||
, tc "'(a -> 'a)"
|
||||
, tc "'()"
|
||||
, tc "'('a)"
|
||||
, pending $ tc "''a" -- issue #249
|
||||
, pending $ tc "'''a" -- issue #249
|
||||
, tc_diff "∀ a . a" $ "a"
|
||||
, tc_diff "∀ a. a" $ "a"
|
||||
, tc_diff "∀ a . 'a" $ "'a"
|
||||
, pending $ tc_diff "∀a . a" $ "a" -- lexer doesn't accept, treats ∀a as one lexeme - feels like it should work
|
||||
, pending $ tc_diff "∀ A . 'A" $ "'A" -- 'unknown parse error' - should this be accepted?
|
||||
|
||||
, tc_diff_rtt False "a -> b -> c -> d" -- hitting 'unexpected Semi' in the reparse
|
||||
"a\n\
|
||||
\-> b\n\
|
||||
\-> c\n\
|
||||
\-> d" 10
|
||||
|
||||
, tc_diff_rtt False "a -> Pair b c -> d" -- ditto, and extra line breaks that seem superfluous in Pair
|
||||
"a\n\
|
||||
\-> Pair b c\n\
|
||||
\-> d" 14
|
||||
|
||||
, tc_diff_rtt False "Pair (forall a. (a -> a -> a)) b" -- as above, and TODO not nesting under Pair
|
||||
"Pair\n\
|
||||
\ (∀ a. a -> a -> a) b" 24
|
||||
|
||||
, tc_diff_rtt False "Pair (forall a. (a -> a -> a)) b" -- as above, and TODO not breaking under forall
|
||||
"Pair\n\
|
||||
\ (∀ a. a -> a -> a)\n\
|
||||
\ b" 21
|
||||
|
||||
]
|
||||
|
@ -30,4 +30,4 @@ isSubtypeTest =
|
||||
where
|
||||
expectSubtype t1 t2 =
|
||||
scope ("isSubtype (" <> show t1 <> ") (" <> show t2 <> ")")
|
||||
(expect $ Typechecker.isSubtype t1 t2)
|
||||
(expect $ Typechecker.isSubtype t1 t2)
|
||||
|
@ -39,4 +39,4 @@ verifyClosedTermTest = tests
|
||||
in do
|
||||
expectEqual 4 (length errors) -- there are 4 unknown symbols: a, a', b, b'
|
||||
for_ errors expectUnknownSymbol
|
||||
]
|
||||
]
|
||||
|
@ -22,4 +22,4 @@ test = scope "var" $ tests [
|
||||
, Var.inferTypeConstructorArg
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
@ -70,7 +70,7 @@ usage = P.callout "🌻" $ P.lines [
|
||||
P.bold "ucm transcript.fork -save-codebase mytranscript.md",
|
||||
P.wrap $ "Executes the `mytranscript.md` transcript in a copy of the current codebase"
|
||||
<> "and creates `mytranscript.output.md` if successful. Exits after completion,"
|
||||
<> "and saves the resulting codebase to a new directory on disk."
|
||||
<> "and saves the resulting codebase to a new directory on disk."
|
||||
<> "Multiple transcript files may be provided; they are processed in sequence"
|
||||
<> "starting from the same codebase.",
|
||||
"",
|
||||
@ -137,11 +137,11 @@ main = do
|
||||
theCodebase <- FileCodebase.getCodebaseOrExit mcodepath
|
||||
let fileEvent = Input.UnisonFileChanged (Text.pack "<standard input>") contents
|
||||
launch currentDir configFilePath theCodebase [Left fileEvent, Right $ Input.ExecuteI mainName, Right Input.QuitI]
|
||||
"transcript" : args' ->
|
||||
"transcript" : args' ->
|
||||
case args' of
|
||||
"-save-codebase" : transcripts -> runTranscripts False True mcodepath transcripts
|
||||
_ -> runTranscripts False False mcodepath args'
|
||||
"transcript.fork" : args' ->
|
||||
"transcript.fork" : args' ->
|
||||
case args' of
|
||||
"-save-codebase" : transcripts -> runTranscripts True True mcodepath transcripts
|
||||
_ -> runTranscripts True False mcodepath args'
|
||||
@ -154,7 +154,7 @@ prepareTranscriptDir inFork mcodepath = do
|
||||
currentDir <- getCurrentDirectory
|
||||
tmp <- Temp.createTempDirectory currentDir "transcript"
|
||||
|
||||
unless inFork $ do
|
||||
unless inFork $ do
|
||||
PT.putPrettyLn . P.wrap $ "Transcript will be run on a new, empty codebase."
|
||||
_ <- FileCodebase.initCodebase tmp
|
||||
pure()
|
||||
@ -193,13 +193,13 @@ runTranscripts' mcodepath transcriptDir args = do
|
||||
(FP.takeExtension md)
|
||||
writeUtf8 out mdOut
|
||||
putStrLn $ "💾 Wrote " <> out
|
||||
wat ->
|
||||
wat ->
|
||||
PT.putPrettyLn $ P.callout "❓" (
|
||||
P.lines [
|
||||
P.indentN 2 "Unrecognized command, skipping:", "",
|
||||
P.indentN 2 $ P.string wat])
|
||||
pure True
|
||||
[] ->
|
||||
[] ->
|
||||
pure False
|
||||
|
||||
runTranscripts :: Bool -> Bool -> Maybe FilePath -> [String] -> IO ()
|
||||
@ -217,7 +217,7 @@ runTranscripts inFork keepTemp mcodepath args = do
|
||||
<> P.backticked ("ucm -codebase " <> P.string transcriptDir)
|
||||
<> "to do more work with it."])
|
||||
|
||||
unless completed $ do
|
||||
unless completed $ do
|
||||
unless keepTemp $ removeDirectoryRecursive transcriptDir
|
||||
PT.putPrettyLn usage
|
||||
Exit.exitWith (Exit.ExitFailure 1)
|
||||
|
@ -559,16 +559,16 @@ components :: Var v => [(v, Term f v a)] -> [[(v, Term f v a)]]
|
||||
components = Components.components freeVars
|
||||
|
||||
-- Converts to strongly connected components while preserving the
|
||||
-- order of definitions. Satisfies `join (orderedComponents bs) == bs`.
|
||||
-- order of definitions. Satisfies `join (orderedComponents bs) == bs`.
|
||||
orderedComponents' :: Var v => [(v, Term f v a)] -> [[(v, Term f v a)]]
|
||||
orderedComponents' tms = go [] Set.empty tms
|
||||
orderedComponents' tms = go [] Set.empty tms
|
||||
where
|
||||
go [] _ [] = []
|
||||
go [] deps (hd:rem) = go [hd] (deps <> freeVars (snd hd)) rem
|
||||
go cur deps rem = case findIndex isDep rem of
|
||||
Nothing -> reverse cur : let (hd,tl) = splitAt 1 rem
|
||||
in go hd (depsFor hd) tl
|
||||
Just i -> go (reverse newMembers ++ cur) deps' (drop (i+1) rem)
|
||||
Just i -> go (reverse newMembers ++ cur) deps' (drop (i+1) rem)
|
||||
where deps' = deps <> depsFor newMembers
|
||||
newMembers = take (i+1) rem
|
||||
where
|
||||
@ -576,7 +576,7 @@ orderedComponents' tms = go [] Set.empty tms
|
||||
isDep (v, _) = Set.member v deps
|
||||
|
||||
-- Like `orderedComponents'`, but further break up cycles and move
|
||||
-- cyclic subcycles before other components in the same cycle.
|
||||
-- cyclic subcycles before other components in the same cycle.
|
||||
-- Tweak suggested by @aryairani.
|
||||
--
|
||||
-- Example: given `[[x],[ping,r,s,pong]]`, where `ping` and `pong`
|
||||
@ -587,7 +587,7 @@ orderedComponents bs0 = tweak =<< orderedComponents' bs0 where
|
||||
tweak :: Var v => [(v,Term f v a)] -> [[(v,Term f v a)]]
|
||||
tweak bs@(_:_:_) = case takeWhile isCyclic (components bs) of
|
||||
[] -> [bs]
|
||||
cycles -> cycles <> orderedComponents rest
|
||||
cycles -> cycles <> orderedComponents rest
|
||||
where
|
||||
rest = [ (v,b) | (v,b) <- bs, Set.notMember v cycleVars ]
|
||||
cycleVars = Set.fromList (fst <$> join cycles)
|
||||
|
@ -37,14 +37,14 @@ data ResolutionFailure v a
|
||||
|
||||
type ResolutionResult v a r = Either (Seq (ResolutionFailure v a)) r
|
||||
|
||||
-- For all names in `ns`, (ex: foo.bar.baz), generate the list of suffixes
|
||||
-- For all names in `ns`, (ex: foo.bar.baz), generate the list of suffixes
|
||||
-- of that name [[foo.bar.baz], [bar.baz], [baz]]. Insert these suffixes
|
||||
-- into a multimap map along with their corresponding refs. Any suffix
|
||||
-- which is unique is added as an entry to `ns`.
|
||||
suffixify0 :: Names0 -> Names0
|
||||
suffixify0 ns = ns <> suffixNs
|
||||
suffixify0 ns = ns <> suffixNs
|
||||
where
|
||||
suffixNs = names0 (R.fromList uniqueTerms) (R.fromList uniqueTypes)
|
||||
suffixNs = names0 (R.fromList uniqueTerms) (R.fromList uniqueTypes)
|
||||
terms = List.multimap [ (n,ref) | (n0,ref) <- R.toList (terms0 ns), n <- Name.suffixes n0 ]
|
||||
types = List.multimap [ (n,ref) | (n0,ref) <- R.toList (types0 ns), n <- Name.suffixes n0 ]
|
||||
uniqueTerms = [ (n,ref) | (n, nubOrd -> [ref]) <- Map.toList terms ]
|
||||
|
@ -39,11 +39,11 @@ readUtf8 p = decodeUtf8 <$> BS.readFile p
|
||||
safeReadUtf8 :: FilePath -> IO (Either IOException Text)
|
||||
safeReadUtf8 p = try (readUtf8 p)
|
||||
|
||||
safeReadUtf8StdIn :: IO (Either IOException Text)
|
||||
safeReadUtf8StdIn :: IO (Either IOException Text)
|
||||
safeReadUtf8StdIn = try $ decodeUtf8 <$> BS.getContents
|
||||
|
||||
writeUtf8 :: FilePath -> Text -> IO ()
|
||||
writeUtf8 p txt = BS.writeFile p (encodeUtf8 txt)
|
||||
writeUtf8 p txt = BS.writeFile p (encodeUtf8 txt)
|
||||
|
||||
reportBug :: String -> String -> String
|
||||
reportBug bugId msg = unlines [
|
||||
|
@ -26,7 +26,7 @@ pattern Con :: Reference -> Int -> ConstructorType -> Referent
|
||||
pattern Con r i t = Con' r i t
|
||||
{-# COMPLETE Ref, Con #-}
|
||||
|
||||
type Id = Referent' R.Id
|
||||
type Id = Referent' R.Id
|
||||
|
||||
data Referent' r = Ref' r | Con' r Int ConstructorType
|
||||
deriving (Show, Ord, Eq, Functor)
|
||||
|
@ -116,14 +116,14 @@ innerJoinDomMultimaps :: (Ord a, Ord b, Ord c)
|
||||
-> Map a (Set b, Set c)
|
||||
innerJoinDomMultimaps b c =
|
||||
Map.fromList
|
||||
[ (a, (lookupDom a b, lookupDom a c))
|
||||
[ (a, (lookupDom a b, lookupDom a c))
|
||||
| a <- S.toList $ dom b `S.intersection` dom c ]
|
||||
|
||||
innerJoinRanMultimaps :: (Ord a, Ord b, Ord c)
|
||||
=> Relation a c
|
||||
-> Relation b c
|
||||
-> Map c (Set a, Set b)
|
||||
innerJoinRanMultimaps a b = innerJoinDomMultimaps (swap a) (swap b)
|
||||
innerJoinRanMultimaps a b = innerJoinDomMultimaps (swap a) (swap b)
|
||||
|
||||
joinDom :: (Ord a, Ord b, Ord c) => Relation a b -> Relation a c -> Relation a (b,c)
|
||||
joinDom b c = swap $ joinRan (swap b) (swap c)
|
||||
|
@ -7,4 +7,4 @@ symmetricDifference :: Ord a => Set a -> Set a -> Set a
|
||||
symmetricDifference a b = (a `difference` b) `union` (b `difference` a)
|
||||
|
||||
mapMaybe :: (Ord a, Ord b) => (a -> Maybe b) -> Set a -> Set b
|
||||
mapMaybe f s = fromList [ r | (f -> Just r) <- toList s ]
|
||||
mapMaybe f s = fromList [ r | (f -> Just r) <- toList s ]
|
||||
|
Loading…
Reference in New Issue
Block a user