Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Synopsis
- data Name
- cons :: HasCallStack => NameSegment -> Name -> Name
- snoc :: Name -> NameSegment -> Name
- joinDot :: HasCallStack => Name -> Name -> Name
- fromSegment :: NameSegment -> Name
- fromSegments :: NonEmpty NameSegment -> Name
- fromReverseSegments :: NonEmpty NameSegment -> Name
- countSegments :: Name -> Int
- isAbsolute :: Name -> Bool
- isRelative :: Name -> Bool
- isPrefixOf :: Name -> Name -> Bool
- beginsWithSegment :: Name -> NameSegment -> Bool
- endsWith :: Name -> Name -> Bool
- endsWithReverseSegments :: Name -> [NameSegment] -> Bool
- endsWithSegments :: Name -> [NameSegment] -> Bool
- stripReversedPrefix :: Name -> [NameSegment] -> Maybe Name
- tryStripReversedPrefix :: Name -> [NameSegment] -> Name
- reverseSegments :: Name -> NonEmpty NameSegment
- segments :: Name -> NonEmpty NameSegment
- suffixes :: Name -> [Name]
- lastSegment :: Name -> NameSegment
- makeAbsolute :: Name -> Name
- makeRelative :: Name -> Name
- setPosition :: Position -> Name -> Name
- parent :: Name -> Maybe Name
- stripNamePrefix :: Name -> Name -> Maybe Name
- unqualified :: Name -> Name
- isUnqualified :: Name -> Bool
- commonPrefix :: Name -> Name -> [NameSegment]
- preferShallowLibDepth :: Ord r => [([Name], r)] -> Set r
- searchByRankedSuffix :: Ord r => Name -> Relation Name r -> Set r
- searchBySuffix :: Ord r => Name -> Relation Name r -> Set r
- filterBySuffix :: Ord r => Name -> Relation Name r -> Relation Name r
- filterByRankedSuffix :: Ord r => Name -> Relation Name r -> Relation Name r
- suffixifyByName :: forall r. Ord r => Name -> Relation Name r -> Name
- suffixifyByHash :: forall r. Ord r => Name -> Relation Name r -> Name
- suffixifyByHashName :: forall r. Ord r => Name -> Relation Name r -> Name
- sortByText :: (a -> Text) -> [a] -> [a]
- sortNamed :: (Name -> Text) -> (a -> Name) -> [a] -> [a]
- sortNames :: (Name -> Text) -> [Name] -> [Name]
- splits :: HasCallStack => Name -> [([NameSegment], Name)]
- suffixFrom :: Name -> Name -> Maybe Name
- class Eq n => Alphabetical n where
- compareAlphabetical :: n -> n -> Ordering
- compareSuffix :: Name -> Name -> Ordering
Documentation
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:
Instances
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.
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.
stripReversedPrefix :: Name -> [NameSegment] -> Maybe Name Source #
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 ascending-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"
isUnqualified :: Name -> Bool Source #
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
filterBySuffix :: Ord r => Name -> Relation Name r -> Relation Name r Source #
Like searchBySuffix
, but also keeps the names around.
filterByRankedSuffix :: Ord r => Name -> Relation Name r -> Relation Name r Source #
Like searchByRankedSuffix
, but also keeps the names around.
sortByText :: (a -> Text) -> [a] -> [a] 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 #
compareAlphabetical :: n -> n -> Ordering #
Instances
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.