Closed adnelson closed 6 years ago
It looks like removePrefix
and removeSuffix
are slight specializations of stripPrefix
and stripSuffix
, e.g.:
removePrefix x y = fromMaybe y (stripPrefix x y)
I would find the presence of both versions of this function in the same library confusing personally. When I need the removePrefix
functionality, I've always done it with fromMaybe
.
As for addPrefix
or addSuffix
: I'd be OK adding them with a rename to ensurePrefix
and ensureSuffix
. The current name doesn't imply to me that it will check if the prefix/suffix is already present.
I think dropEnd
can simply be added to IsSequence
as you've defined it, and then provide overrides for more efficient behavior in some instances.
I'm not sure, but I believe the reason we don't have a split
function right now is because that name means different things throughout the Haskell ecosystem. Is there a reason that splitWhen
is insufficient?
Thanks for the response! I learned a few things here.
splitWhen
is exactly Data.Text.split
, which is what I was looking for! I just wasn't able to find that one. :smile: stripPrefix
; I agree there's no need for removePrefix
when we have that.ensurePrefix
and ensureSuffix
. No objection to those names. dropEnd
into a PR.I've actually wanted removePrefix
a few times myself.
removePrefix x y = fromMaybe y (stripPrefix x y)
It is simple enough to just use fromMaybe
, but because you end up using the last argument (y
) twice, it's not very convenient when writing in point-free style.
It'd be nice to use removePrefix
when using the deriveJSON
function from Aeson:
data Foo = Foo
{ fooA :: Int
, fooB :: String
}
$(deriveJSON defaultOptions { fieldLabelModifier = removePrefix "foo" } ''Foo)
Without removePrefix
this code looks like the following:
$(deriveJSON defaultOptions { fieldLabelModifier = \s -> fromMaybe s (stripPrefix "foo" s) } ''Foo)
As an aside, defaultOptions
and Options
are defined as the following:
defaultOptions :: Options
defaultOptions =
Options
{ fieldLabelModifier = id
, ...
}
data Options = Options
{ fieldLabelModifier :: String -> String
-- ^ Function applied to field labels.
-- Handy for removing common record prefixes for example.
, ...
}
Of course, removePrefix
could be defined locally, but I think it would be a nice addition to Data.Sequences
.
As long as the types are different for removePrefix
and stripPrefix
(and as long as there is a short example for each of them in the documentation), I don't think it would too confusing for end users.
I'm not too opinionated on it to be honest. I'd prefer a name that was more explicit about the difference, but if you send a PR, I'll accept even with the removePrefix
name.
@snoyberg I agree. The only thing I dislike about it as well is the similarity between the names stripPrefix
and removePrefix
.
If you (or anyone else) has an idea for a better name I'd be interested in hearing it.
Here's some similar names (but none of which I really like):
removePrefix
dropPrefix
takeOffPrefix
deletePrefix
getRidOfPrefix
withoutPrefix
If I send a PR for this, should I also add a similar removeSuffix
(or whatever it will be called) function as well?
I'd definitely go for including a *Suffix
version at the same time. drop
and delete
both seem nice here, since both verbs have an existing meaning in the Haskell world of doing nothing if not possible (e.g., drop 5 [] == []
, and Map.delete nonExistentKey m == m
). I'd lean towards dropPrefix
.
Okay, I'll send a PR adding both dropPrefix
and dropSuffix
.
There are a couple of functions which I would love to have in this library, but I'm not sure what the correct classes to put them in would be:
dropEnd
, analogous to drop but from the end of the sequence.addPrefix
,removePrefix
,addSuffix
,removeSuffix
. Idempotent removal/addition from beginning/end of sequences.split
, for splitting a sequence into subsequences according to some predicate. SimilarlysplitOn
.I've made written generic versions of all of the above except
split
, but putting them in the appropriate type class(es) could make them more efficient. For exampleText
andByteString
have their own implementations ofdropEnd
which are undoubtedly more efficient than the one I have here.Admittedly the prefix/suffix stuff might be too specific to put into a generic library like this one, but I'm not sure. In any case I'd be happy to make a PR if that's desired, and get some guidance on what classes we'd want to put these in.