unison-core1-0.0.0
Safe HaskellSafe-Inferred
LanguageHaskell2010

Unison.Name

Synopsis

Documentation

data Name Source #

A name is an absolute-or-relative non-empty list of name segments. It is used to represent the path to a definition.

A few example names:

  • "foo.bar" --> Name Relative ("bar" :| ["foo"])
  • ".foo.bar" --> Name Absolute ("bar" :| ["foo"])
  • "|>.-- Name Relative (":| ["|"])
  • "." --> Name Relative ("." :| [])
  • ".." --> Name Absolute (".." :| [])

Instances

Instances details
(TypeError ('Text "You cannot make a Name from a string literal because there may (some day) be more than one syntax") :: Constraint) => IsString Name Source # 
Instance details

Defined in Unison.Name.Internal

Methods

fromString :: String -> Name #

Generic Name Source # 
Instance details

Defined in Unison.Name.Internal

Associated Types

type Rep Name :: Type -> Type #

Methods

from :: Name -> Rep Name x #

to :: Rep Name x -> Name #

Show Name Source # 
Instance details

Defined in Unison.Name.Internal

Methods

showsPrec :: Int -> Name -> ShowS #

show :: Name -> String #

showList :: [Name] -> ShowS #

Eq Name Source # 
Instance details

Defined in Unison.Name.Internal

Methods

(==) :: Name -> Name -> Bool #

(/=) :: Name -> Name -> Bool #

Ord Name Source # 
Instance details

Defined in Unison.Name.Internal

Methods

compare :: Name -> Name -> Ordering #

(<) :: Name -> Name -> Bool #

(<=) :: Name -> Name -> Bool #

(>) :: Name -> Name -> Bool #

(>=) :: Name -> Name -> Bool #

max :: Name -> Name -> Name #

min :: Name -> Name -> Name #

Alphabetical Name Source #

Compare names (kinda) alphabetically: absolute comes before relative, but otherwise compare the name segments alphabetically, in order.

Instance details

Defined in Unison.Name.Internal

Snoc Name Name NameSegment NameSegment Source # 
Instance details

Defined in Unison.Name.Internal

type Rep Name Source # 
Instance details

Defined in Unison.Name.Internal

type Rep Name = D1 ('MetaData "Name" "Unison.Name.Internal" "unison-core1-0.0.0-Kp7ZcNnt5XdB8ImvFwyntI" 'False) (C1 ('MetaCons "Name" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Position) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (NonEmpty NameSegment))))

Basic construction

cons :: HasCallStack => NameSegment -> Name -> Name Source #

Cons a name segment onto the head of a relative name. Not monotonic with respect to ordering! It is not safe to use cons s as the first argument to Map.mapKeysMonotonic!

Precondition: the name is relative

O(n), where n is the number of segments.

snoc :: Name -> NameSegment -> Name Source #

Snoc a name segment onto the end of a name.

O(1).

fromSegment :: NameSegment -> Name Source #

Construct a relative name from a name segment.

O(1).

fromSegments :: NonEmpty NameSegment -> Name Source #

Construct a relative name from a list of name segments.

>>> fromSegments ("a" :| ["b", "c"])
"a.b.c"

O(n), where n is the number of name segments.

fromReverseSegments :: NonEmpty NameSegment -> Name Source #

Construct a relative name from a list of name segments which are in reverse order

>>> fromReverseSegments ("c" :| ["b", "a"])
a.b.c

O(1)

Basic queries

countSegments :: Name -> Int Source #

Return the number of name segments in a name.

O(n), where n is the number of name segments.

isAbsolute :: Name -> Bool Source #

Is this name absolute?

O(1).

isRelative :: Name -> Bool Source #

Is this name relative?

O(1).

isPrefixOf :: Name -> Name -> Bool Source #

isPrefixOf x y returns whether x is a prefix of (or equivalent to) y, which is false if one name is relative and the other is absolute.

>>> isPrefixOf "a.b" "a.b.c"
True
>>> isPrefixOf "a.b.c" "a.b.c"
True
>>> isPrefixOf ".a.b" "a.b.c"
False

O(n), where n is the number of name segments.

beginsWithSegment :: Name -> NameSegment -> Bool Source #

beginsWithSegment name segment returns whether name's first name segment is segment.

>>> beginsWithSegment "abc.def" "abc"
True
>>> beginsWithSegment "abc.def" "ab"
False

O(n), where n is the number of name segments.

endsWithReverseSegments :: Name -> [NameSegment] -> Bool Source #

Like endsWithSegments, but accepts a list of name segments in reverse order.

Slightly more efficient than endsWithSegments.

>>> endsWithReverseSegments "a.b.c" ["c", "b"]
True

endsWithSegments :: Name -> [NameSegment] -> Bool Source #

endsWithSegments x y returns whether x ends with y.

>>> endsWithSegments "a.b.c" ["b", "c"]
True
>>> endsWithSegments "a.b.c" ["d"]
False
>>> endsWithSegments "a.b.c" []
True

O(n), where n is the number of name segments.

tryStripReversedPrefix :: Name -> [NameSegment] -> Name Source #

Like stripReversedPrefix but if the prefix doesn't match, or if it would strip the entire name away just return the original name.

>>> tryStripReversedPrefix (fromReverseSegments ("c" :| ["b", "a"])) ["b", "a"]
Name Relative (NameSegment {toText = "c"} :| [])
>>> tryStripReversedPrefix (fromReverseSegments ("y" :| ["x"])) ["b", "a"]
Name Relative (NameSegment {toText = "y"} :| [NameSegment {toText = "x"}])
>>> tryStripReversedPrefix (fromReverseSegments ("c" :| ["b", "a"])) ["b", "a"]
Name Relative (NameSegment {toText = "c"} :| [])

reverseSegments :: Name -> NonEmpty NameSegment Source #

Return the name segments of a name, in reverse order.

>>> reverseSegments "a.b.c"
"c" :| ["b", "a"]

O(1).

segments :: Name -> NonEmpty NameSegment Source #

Return the name segments of a name.

>>> segments "a.b.c"
"a" :| ["b", "c"]

O(n), where n is the number of name segments.

suffixes :: Name -> [Name] Source #

Return all relative suffixes of a name, in descending-length order. The returned list will always be non-empty.

>>> suffixes "a.b.c"
["a.b.c", "a.b", "c"]
>>> suffixes ".a.b.c"
["a.b.c", "a.b", "c"]

lastSegment :: Name -> NameSegment Source #

Return the final segment of a name.

>>> lastSegment (fromSegments ("base" :| ["List", "map"]))
NameSegment {toText = "map"}

Basic manipulation

makeAbsolute :: Name -> Name Source #

Make a name absolute. No-op if the name is already absolute.

O(1).

makeRelative :: Name -> Name Source #

Make a name relative. No-op if the name is already relative.

O(1).

setPosition :: Position -> Name -> Name Source #

Overwrite a name's position. This only changes the name's tag, it performs no manipulations to the segments of the name.

O(1).

parent :: Name -> Maybe Name Source #

Compute the "parent" of a name, unless the name is only a single segment, in which case it has no parent.

>>> parent "a.b.c"
Just "a.b"
>>> parent ".a.b.c"
Just ".a.b"
>>> parent "a"
Nothing

stripNamePrefix :: Name -> Name -> Maybe Name Source #

stripNamePrefix x y strips prefix x from name y, and returns the resulting name. Returns Nothing x is not a proper (meaning shorter-than) prefix of y.

>>> stripNamePrefix "a.b" "a.b.c"
Just "c"
>>> stripNamePrefix ".a.b" "a.b.c"
Nothing
>>> stripNamePrefix "a.b.c" "a.b.c"
Nothing

unqualified :: Name -> Name Source #

Drop all leading segments from a name, retaining only the last segment as a relative name.

>>> unqualified "a.b.c"
"c"
>>> unqualified ".a.b.c"
"c"

To organize later

commonPrefix :: Name -> Name -> [NameSegment] Source #

Returns the common prefix of two names as segments

Note: the returned segments are NOT reversed.

>>> commonPrefix "a.b.x" "a.b.y"
[a,b]
>>> commonPrefix "x.y.z" "a.b.c"
[]
>>> commonPrefix "a.b.c" "a.b.c.d.e"
[a,b,c]

Must have equivalent positions or no there's no common prefix >>> commonPrefix ".a.b.c" "a.b.c.d.e" []

Prefix matches are performed at the *segment* level: >>> commonPrefix "a.bears" "a.beats" [a]

preferShallowLibDepth :: Ord r => [([Name], r)] -> Set r Source #

precondition: input list is deduped, and so is the Name list in the tuple

suffixifyByName :: forall r. Ord r => Name -> Relation Name r -> Name Source #

suffixifyByHash :: forall r. Ord r => Name -> Relation Name r -> Name Source #

suffixifyByHashName :: forall r. Ord r => Name -> Relation Name r -> Name Source #

sortByText :: (a -> Text) -> [a] -> [a] Source #

sortNamed :: (Name -> Text) -> (a -> Name) -> [a] -> [a] Source #

sortNames :: (Name -> Text) -> [Name] -> [Name] Source #

splits :: HasCallStack => Name -> [([NameSegment], Name)] Source #

Return all "splits" of a relative name, which pair a possibly-empty prefix of name segments with a suffix, such that the original name is equivalent to prefix + suffix.

Note: always returns a non-empty list, but (currently) does not use NonEmpty for convenience, as none of the call-sites care if the list is empty or not.

> splits foo.bar.baz

  prefix    suffix
  ------    ------
  ∅         foo.bar.baz
  foo       bar.baz
  foo.bar   baz

Precondition: the name is relative.

Re-exports

class Eq n => Alphabetical n where #

Methods

compareAlphabetical :: n -> n -> Ordering #

Instances

Instances details
Alphabetical Text 
Instance details

Defined in Unison.Util.Alphabetical

Alphabetical NameSegment 
Instance details

Defined in Unison.NameSegment.Internal

Alphabetical Name Source #

Compare names (kinda) alphabetically: absolute comes before relative, but otherwise compare the name segments alphabetically, in order.

Instance details

Defined in Unison.Name.Internal

Alphabetical a => Alphabetical (NonEmpty a) 
Instance details

Defined in Unison.Util.Alphabetical

Alphabetical n => Alphabetical (HashQualified n) Source # 
Instance details

Defined in Unison.HashQualified

Alphabetical n => Alphabetical (HashQualified n) Source # 
Instance details

Defined in Unison.HashQualifiedPrime

Alphabetical a => Alphabetical (Maybe a) 
Instance details

Defined in Unison.Util.Alphabetical

Alphabetical a => Alphabetical [a] 
Instance details

Defined in Unison.Util.Alphabetical

Methods

compareAlphabetical :: [a] -> [a] -> Ordering #

Exported for testing

compareSuffix :: Name -> Name -> Ordering Source #

compareSuffix x y compares the suffix of y (in reverse segment order) that is as long as x to x (in reverse segment order).

>>> compareSuffix "b.c" "a.b.c"
EQ -- because [c,b] == [c,b]
>>> compareSuffix "b.c" "a.b.b"
LT -- because [b,b] < [c,b]
>>> compareSuffix "a.b.c" "b.c"
LT -- because [c,b] < [c,b,a]
>>> compareSuffix "b.b" "a.b.c"
GT -- because [c,b] > [b,b]

Used for suffix-based lookup of a name. For instance, given a r : Relation Name x, Relation.searchDom (compareSuffix "foo.bar") r will find all r whose name has foo.bar as a suffix.

This is only exported for testing; use searchBySuffix or shortestUniqueSuffix instead.

O(n), where n is the number of name segments.