emojis 0.1.3 → 0.1.4
raw patch · 6 files changed
+258/−14 lines, 6 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Text.Emoji: replaceEmojis :: (Text -> [Text] -> Text) -> Text -> Text
Files
- changelog.md +13/−6
- emojis.cabal +3/−2
- src/Text/Emoji.hs +31/−0
- src/Text/emojis.inc +124/−6
- src/Trie.hs +83/−0
- test/test.hs +4/−0
changelog.md view
@@ -1,12 +1,15 @@ # emojis -## 0.1+# 0.1.4 - * Initial release+ * Update emoji data.+ * Export new function `replaceEmojis`, allowing replacement of+ emojis in a Text with alternate text.+ * Drop support for ghc < 8.8. -# 0.1.1+# 0.1.3 - * Update emoji data.+ * Update emoji data to Unicode Emoji 15.0 and aliases from gemoji. # 0.1.2 @@ -16,6 +19,10 @@ complete list of emojis, including emojis for which gemoji provides no alias (Stephen Morgan). -# 0.1.3+# 0.1.1 - * Update emoji data to Unicode Emoji 15.0 and aliases from gemoji.+ * Update emoji data.++## 0.1++ * Initial release
emojis.cabal view
@@ -1,5 +1,5 @@ name: emojis-version: 0.1.3+version: 0.1.4 synopsis: Conversion between emoji characters and their names. description: This package provides functions for converting emoji names to emoji characters and vice versa.@@ -27,7 +27,8 @@ library hs-source-dirs: src exposed-modules: Text.Emoji- build-depends: base >= 4.9 && < 5,+ other-modules: Trie+ build-depends: base >= 4.13 && < 5, text, containers default-language: Haskell2010
src/Text/Emoji.hs view
@@ -5,13 +5,18 @@ ( emojis , emojiFromAlias , aliasesFromEmoji+, replaceEmojis , baseEmojis , zwjEmojis ) where import Prelude+import Data.Char (chr, ord) import qualified Data.Map as M import Data.Text (Text)+import qualified Data.Text as T+import Data.Bifunctor (first)+import Trie as Trie emojiMap :: M.Map Text Text emojiMap = M.fromList emojis@@ -30,6 +35,32 @@ -- | Lookup the aliases of an emoji. aliasesFromEmoji :: Text -> Maybe [Text] aliasesFromEmoji s = M.lookup s emojiAliasMap++-- | Replace emojis in a text with alternative text.+-- The replacement function maps an emoji and a list of emoji aliases+-- to a replacement text.+replaceEmojis :: (Text -> [Text] -> Text) -> Text -> Text+replaceEmojis getReplacement = fromCodePoints . go . toCodePoints+ where+ go [] = []+ go (c:cs) =+ case Trie.matchLongestPrefix emojiTrie (c:cs) of+ Just (aliases, numcps, _subtrie) ->+ let (consumed, remaining) = splitAt numcps (c:cs)+ in toCodePoints (getReplacement (fromCodePoints consumed) aliases)+ <> go remaining+ Nothing -> -- go forward one UTF8 code point+ c : go cs++toCodePoints :: Text -> [Int]+toCodePoints = map ord . T.unpack++fromCodePoints :: [Int] -> Text+fromCodePoints = T.pack . map chr++emojiTrie :: Trie.Trie [Text]+emojiTrie =+ Trie.fromList . map (first toCodePoints) . M.toList $ emojiAliasMap -- | Association list of (alias, emoji) pairs. Note that the -- same emoji may have multiple aliases.
src/Text/emojis.inc view
@@ -4506,6 +4506,10 @@ , "\128105\127999\8205\129309\8205\128105\127997" , "\128105\127999\8205\129309\8205\128105\127998" , "\129489\8205\129309\8205\129489"+ , "\129489\8205\129489\8205\129490"+ , "\129489\8205\129489\8205\129490\8205\129490"+ , "\129489\8205\129490"+ , "\129489\8205\129490\8205\129490" , "\129489\127995\8205\10084\65039\8205\128139\8205\129489\127996" , "\129489\127995\8205\10084\65039\8205\128139\8205\129489\127997" , "\129489\127995\8205\10084\65039\8205\128139\8205\129489\127998"@@ -4514,7 +4518,6 @@ , "\129489\127995\8205\10084\65039\8205\129489\127997" , "\129489\127995\8205\10084\65039\8205\129489\127998" , "\129489\127995\8205\10084\65039\8205\129489\127999"- , "\129489\127995\8205\127876" , "\129489\127995\8205\129309\8205\129489\127995" , "\129489\127995\8205\129309\8205\129489\127996" , "\129489\127995\8205\129309\8205\129489\127997"@@ -4528,7 +4531,6 @@ , "\129489\127996\8205\10084\65039\8205\129489\127997" , "\129489\127996\8205\10084\65039\8205\129489\127998" , "\129489\127996\8205\10084\65039\8205\129489\127999"- , "\129489\127996\8205\127876" , "\129489\127996\8205\129309\8205\129489\127995" , "\129489\127996\8205\129309\8205\129489\127996" , "\129489\127996\8205\129309\8205\129489\127997"@@ -4542,7 +4544,6 @@ , "\129489\127997\8205\10084\65039\8205\129489\127996" , "\129489\127997\8205\10084\65039\8205\129489\127998" , "\129489\127997\8205\10084\65039\8205\129489\127999"- , "\129489\127997\8205\127876" , "\129489\127997\8205\129309\8205\129489\127995" , "\129489\127997\8205\129309\8205\129489\127996" , "\129489\127997\8205\129309\8205\129489\127997"@@ -4556,7 +4557,6 @@ , "\129489\127998\8205\10084\65039\8205\129489\127996" , "\129489\127998\8205\10084\65039\8205\129489\127997" , "\129489\127998\8205\10084\65039\8205\129489\127999"- , "\129489\127998\8205\127876" , "\129489\127998\8205\129309\8205\129489\127995" , "\129489\127998\8205\129309\8205\129489\127996" , "\129489\127998\8205\129309\8205\129489\127997"@@ -4570,7 +4570,6 @@ , "\129489\127999\8205\10084\65039\8205\129489\127996" , "\129489\127999\8205\10084\65039\8205\129489\127997" , "\129489\127999\8205\10084\65039\8205\129489\127998"- , "\129489\127999\8205\127876" , "\129489\127999\8205\129309\8205\129489\127995" , "\129489\127999\8205\129309\8205\129489\127996" , "\129489\127999\8205\129309\8205\129489\127997"@@ -4596,6 +4595,12 @@ , "\129777\127999\8205\129778\127996" , "\129777\127999\8205\129778\127997" , "\129777\127999\8205\129778\127998"+ , "\127939\8205\10145\65039"+ , "\127939\127995\8205\10145\65039"+ , "\127939\127996\8205\10145\65039"+ , "\127939\127997\8205\10145\65039"+ , "\127939\127998\8205\10145\65039"+ , "\127939\127999\8205\10145\65039" , "\128104\8205\9877\65039" , "\128104\8205\9878\65039" , "\128104\8205\9992\65039"@@ -4614,8 +4619,11 @@ , "\128104\8205\128640" , "\128104\8205\128658" , "\128104\8205\129455"+ , "\128104\8205\129455\8205\10145\65039" , "\128104\8205\129468"+ , "\128104\8205\129468\8205\10145\65039" , "\128104\8205\129469"+ , "\128104\8205\129469\8205\10145\65039" , "\128104\127995\8205\9877\65039" , "\128104\127995\8205\9878\65039" , "\128104\127995\8205\9992\65039"@@ -4634,8 +4642,11 @@ , "\128104\127995\8205\128640" , "\128104\127995\8205\128658" , "\128104\127995\8205\129455"+ , "\128104\127995\8205\129455\8205\10145\65039" , "\128104\127995\8205\129468"+ , "\128104\127995\8205\129468\8205\10145\65039" , "\128104\127995\8205\129469"+ , "\128104\127995\8205\129469\8205\10145\65039" , "\128104\127996\8205\9877\65039" , "\128104\127996\8205\9878\65039" , "\128104\127996\8205\9992\65039"@@ -4654,8 +4665,11 @@ , "\128104\127996\8205\128640" , "\128104\127996\8205\128658" , "\128104\127996\8205\129455"+ , "\128104\127996\8205\129455\8205\10145\65039" , "\128104\127996\8205\129468"+ , "\128104\127996\8205\129468\8205\10145\65039" , "\128104\127996\8205\129469"+ , "\128104\127996\8205\129469\8205\10145\65039" , "\128104\127997\8205\9877\65039" , "\128104\127997\8205\9878\65039" , "\128104\127997\8205\9992\65039"@@ -4674,8 +4688,11 @@ , "\128104\127997\8205\128640" , "\128104\127997\8205\128658" , "\128104\127997\8205\129455"+ , "\128104\127997\8205\129455\8205\10145\65039" , "\128104\127997\8205\129468"+ , "\128104\127997\8205\129468\8205\10145\65039" , "\128104\127997\8205\129469"+ , "\128104\127997\8205\129469\8205\10145\65039" , "\128104\127998\8205\9877\65039" , "\128104\127998\8205\9878\65039" , "\128104\127998\8205\9992\65039"@@ -4694,8 +4711,11 @@ , "\128104\127998\8205\128640" , "\128104\127998\8205\128658" , "\128104\127998\8205\129455"+ , "\128104\127998\8205\129455\8205\10145\65039" , "\128104\127998\8205\129468"+ , "\128104\127998\8205\129468\8205\10145\65039" , "\128104\127998\8205\129469"+ , "\128104\127998\8205\129469\8205\10145\65039" , "\128104\127999\8205\9877\65039" , "\128104\127999\8205\9878\65039" , "\128104\127999\8205\9992\65039"@@ -4714,8 +4734,11 @@ , "\128104\127999\8205\128640" , "\128104\127999\8205\128658" , "\128104\127999\8205\129455"+ , "\128104\127999\8205\129455\8205\10145\65039" , "\128104\127999\8205\129468"+ , "\128104\127999\8205\129468\8205\10145\65039" , "\128104\127999\8205\129469"+ , "\128104\127999\8205\129469\8205\10145\65039" , "\128105\8205\9877\65039" , "\128105\8205\9878\65039" , "\128105\8205\9992\65039"@@ -4734,8 +4757,11 @@ , "\128105\8205\128640" , "\128105\8205\128658" , "\128105\8205\129455"+ , "\128105\8205\129455\8205\10145\65039" , "\128105\8205\129468"+ , "\128105\8205\129468\8205\10145\65039" , "\128105\8205\129469"+ , "\128105\8205\129469\8205\10145\65039" , "\128105\127995\8205\9877\65039" , "\128105\127995\8205\9878\65039" , "\128105\127995\8205\9992\65039"@@ -4754,8 +4780,11 @@ , "\128105\127995\8205\128640" , "\128105\127995\8205\128658" , "\128105\127995\8205\129455"+ , "\128105\127995\8205\129455\8205\10145\65039" , "\128105\127995\8205\129468"+ , "\128105\127995\8205\129468\8205\10145\65039" , "\128105\127995\8205\129469"+ , "\128105\127995\8205\129469\8205\10145\65039" , "\128105\127996\8205\9877\65039" , "\128105\127996\8205\9878\65039" , "\128105\127996\8205\9992\65039"@@ -4774,8 +4803,11 @@ , "\128105\127996\8205\128640" , "\128105\127996\8205\128658" , "\128105\127996\8205\129455"+ , "\128105\127996\8205\129455\8205\10145\65039" , "\128105\127996\8205\129468"+ , "\128105\127996\8205\129468\8205\10145\65039" , "\128105\127996\8205\129469"+ , "\128105\127996\8205\129469\8205\10145\65039" , "\128105\127997\8205\9877\65039" , "\128105\127997\8205\9878\65039" , "\128105\127997\8205\9992\65039"@@ -4794,8 +4826,11 @@ , "\128105\127997\8205\128640" , "\128105\127997\8205\128658" , "\128105\127997\8205\129455"+ , "\128105\127997\8205\129455\8205\10145\65039" , "\128105\127997\8205\129468"+ , "\128105\127997\8205\129468\8205\10145\65039" , "\128105\127997\8205\129469"+ , "\128105\127997\8205\129469\8205\10145\65039" , "\128105\127998\8205\9877\65039" , "\128105\127998\8205\9878\65039" , "\128105\127998\8205\9992\65039"@@ -4814,8 +4849,11 @@ , "\128105\127998\8205\128640" , "\128105\127998\8205\128658" , "\128105\127998\8205\129455"+ , "\128105\127998\8205\129455\8205\10145\65039" , "\128105\127998\8205\129468"+ , "\128105\127998\8205\129468\8205\10145\65039" , "\128105\127998\8205\129469"+ , "\128105\127998\8205\129469\8205\10145\65039" , "\128105\127999\8205\9877\65039" , "\128105\127999\8205\9878\65039" , "\128105\127999\8205\9992\65039"@@ -4834,14 +4872,30 @@ , "\128105\127999\8205\128640" , "\128105\127999\8205\128658" , "\128105\127999\8205\129455"+ , "\128105\127999\8205\129455\8205\10145\65039" , "\128105\127999\8205\129468"+ , "\128105\127999\8205\129468\8205\10145\65039" , "\128105\127999\8205\129469"+ , "\128105\127999\8205\129469\8205\10145\65039"+ , "\128694\8205\10145\65039"+ , "\128694\127995\8205\10145\65039"+ , "\128694\127996\8205\10145\65039"+ , "\128694\127997\8205\10145\65039"+ , "\128694\127998\8205\10145\65039"+ , "\128694\127999\8205\10145\65039"+ , "\129486\8205\10145\65039"+ , "\129486\127995\8205\10145\65039"+ , "\129486\127996\8205\10145\65039"+ , "\129486\127997\8205\10145\65039"+ , "\129486\127998\8205\10145\65039"+ , "\129486\127999\8205\10145\65039" , "\129489\8205\9877\65039" , "\129489\8205\9878\65039" , "\129489\8205\9992\65039" , "\129489\8205\127806" , "\129489\8205\127859" , "\129489\8205\127868"+ , "\129489\8205\127876" , "\129489\8205\127891" , "\129489\8205\127908" , "\129489\8205\127912"@@ -4854,14 +4908,18 @@ , "\129489\8205\128640" , "\129489\8205\128658" , "\129489\8205\129455"+ , "\129489\8205\129455\8205\10145\65039" , "\129489\8205\129468"+ , "\129489\8205\129468\8205\10145\65039" , "\129489\8205\129469"+ , "\129489\8205\129469\8205\10145\65039" , "\129489\127995\8205\9877\65039" , "\129489\127995\8205\9878\65039" , "\129489\127995\8205\9992\65039" , "\129489\127995\8205\127806" , "\129489\127995\8205\127859" , "\129489\127995\8205\127868"+ , "\129489\127995\8205\127876" , "\129489\127995\8205\127891" , "\129489\127995\8205\127908" , "\129489\127995\8205\127912"@@ -4874,14 +4932,18 @@ , "\129489\127995\8205\128640" , "\129489\127995\8205\128658" , "\129489\127995\8205\129455"+ , "\129489\127995\8205\129455\8205\10145\65039" , "\129489\127995\8205\129468"+ , "\129489\127995\8205\129468\8205\10145\65039" , "\129489\127995\8205\129469"+ , "\129489\127995\8205\129469\8205\10145\65039" , "\129489\127996\8205\9877\65039" , "\129489\127996\8205\9878\65039" , "\129489\127996\8205\9992\65039" , "\129489\127996\8205\127806" , "\129489\127996\8205\127859" , "\129489\127996\8205\127868"+ , "\129489\127996\8205\127876" , "\129489\127996\8205\127891" , "\129489\127996\8205\127908" , "\129489\127996\8205\127912"@@ -4894,14 +4956,18 @@ , "\129489\127996\8205\128640" , "\129489\127996\8205\128658" , "\129489\127996\8205\129455"+ , "\129489\127996\8205\129455\8205\10145\65039" , "\129489\127996\8205\129468"+ , "\129489\127996\8205\129468\8205\10145\65039" , "\129489\127996\8205\129469"+ , "\129489\127996\8205\129469\8205\10145\65039" , "\129489\127997\8205\9877\65039" , "\129489\127997\8205\9878\65039" , "\129489\127997\8205\9992\65039" , "\129489\127997\8205\127806" , "\129489\127997\8205\127859" , "\129489\127997\8205\127868"+ , "\129489\127997\8205\127876" , "\129489\127997\8205\127891" , "\129489\127997\8205\127908" , "\129489\127997\8205\127912"@@ -4914,14 +4980,18 @@ , "\129489\127997\8205\128640" , "\129489\127997\8205\128658" , "\129489\127997\8205\129455"+ , "\129489\127997\8205\129455\8205\10145\65039" , "\129489\127997\8205\129468"+ , "\129489\127997\8205\129468\8205\10145\65039" , "\129489\127997\8205\129469"+ , "\129489\127997\8205\129469\8205\10145\65039" , "\129489\127998\8205\9877\65039" , "\129489\127998\8205\9878\65039" , "\129489\127998\8205\9992\65039" , "\129489\127998\8205\127806" , "\129489\127998\8205\127859" , "\129489\127998\8205\127868"+ , "\129489\127998\8205\127876" , "\129489\127998\8205\127891" , "\129489\127998\8205\127908" , "\129489\127998\8205\127912"@@ -4934,14 +5004,18 @@ , "\129489\127998\8205\128640" , "\129489\127998\8205\128658" , "\129489\127998\8205\129455"+ , "\129489\127998\8205\129455\8205\10145\65039" , "\129489\127998\8205\129468"+ , "\129489\127998\8205\129468\8205\10145\65039" , "\129489\127998\8205\129469"+ , "\129489\127998\8205\129469\8205\10145\65039" , "\129489\127999\8205\9877\65039" , "\129489\127999\8205\9878\65039" , "\129489\127999\8205\9992\65039" , "\129489\127999\8205\127806" , "\129489\127999\8205\127859" , "\129489\127999\8205\127868"+ , "\129489\127999\8205\127876" , "\129489\127999\8205\127891" , "\129489\127999\8205\127908" , "\129489\127999\8205\127912"@@ -4954,8 +5028,11 @@ , "\129489\127999\8205\128640" , "\129489\127999\8205\128658" , "\129489\127999\8205\129455"+ , "\129489\127999\8205\129455\8205\10145\65039" , "\129489\127999\8205\129468"+ , "\129489\127999\8205\129468\8205\10145\65039" , "\129489\127999\8205\129469"+ , "\129489\127999\8205\129469\8205\10145\65039" , "\9977\127995\8205\9792\65039" , "\9977\127995\8205\9794\65039" , "\9977\127996\8205\9792\65039"@@ -4969,17 +5046,29 @@ , "\9977\65039\8205\9792\65039" , "\9977\65039\8205\9794\65039" , "\127939\8205\9792\65039"+ , "\127939\8205\9792\65039\8205\10145\65039" , "\127939\8205\9794\65039"+ , "\127939\8205\9794\65039\8205\10145\65039" , "\127939\127995\8205\9792\65039"+ , "\127939\127995\8205\9792\65039\8205\10145\65039" , "\127939\127995\8205\9794\65039"+ , "\127939\127995\8205\9794\65039\8205\10145\65039" , "\127939\127996\8205\9792\65039"+ , "\127939\127996\8205\9792\65039\8205\10145\65039" , "\127939\127996\8205\9794\65039"+ , "\127939\127996\8205\9794\65039\8205\10145\65039" , "\127939\127997\8205\9792\65039"+ , "\127939\127997\8205\9792\65039\8205\10145\65039" , "\127939\127997\8205\9794\65039"+ , "\127939\127997\8205\9794\65039\8205\10145\65039" , "\127939\127998\8205\9792\65039"+ , "\127939\127998\8205\9792\65039\8205\10145\65039" , "\127939\127998\8205\9794\65039"+ , "\127939\127998\8205\9794\65039\8205\10145\65039" , "\127939\127999\8205\9792\65039"+ , "\127939\127999\8205\9792\65039\8205\10145\65039" , "\127939\127999\8205\9794\65039"+ , "\127939\127999\8205\9794\65039\8205\10145\65039" , "\127940\8205\9792\65039" , "\127940\8205\9794\65039" , "\127940\127995\8205\9792\65039"@@ -5259,17 +5348,29 @@ , "\128693\127999\8205\9792\65039" , "\128693\127999\8205\9794\65039" , "\128694\8205\9792\65039"+ , "\128694\8205\9792\65039\8205\10145\65039" , "\128694\8205\9794\65039"+ , "\128694\8205\9794\65039\8205\10145\65039" , "\128694\127995\8205\9792\65039"+ , "\128694\127995\8205\9792\65039\8205\10145\65039" , "\128694\127995\8205\9794\65039"+ , "\128694\127995\8205\9794\65039\8205\10145\65039" , "\128694\127996\8205\9792\65039"+ , "\128694\127996\8205\9792\65039\8205\10145\65039" , "\128694\127996\8205\9794\65039"+ , "\128694\127996\8205\9794\65039\8205\10145\65039" , "\128694\127997\8205\9792\65039"+ , "\128694\127997\8205\9792\65039\8205\10145\65039" , "\128694\127997\8205\9794\65039"+ , "\128694\127997\8205\9794\65039\8205\10145\65039" , "\128694\127998\8205\9792\65039"+ , "\128694\127998\8205\9792\65039\8205\10145\65039" , "\128694\127998\8205\9794\65039"+ , "\128694\127998\8205\9794\65039\8205\10145\65039" , "\128694\127999\8205\9792\65039"+ , "\128694\127999\8205\9792\65039\8205\10145\65039" , "\128694\127999\8205\9794\65039"+ , "\128694\127999\8205\9794\65039\8205\10145\65039" , "\129318\8205\9792\65039" , "\129318\8205\9794\65039" , "\129318\127995\8205\9792\65039"@@ -5393,17 +5494,29 @@ , "\129485\127999\8205\9792\65039" , "\129485\127999\8205\9794\65039" , "\129486\8205\9792\65039"+ , "\129486\8205\9792\65039\8205\10145\65039" , "\129486\8205\9794\65039"+ , "\129486\8205\9794\65039\8205\10145\65039" , "\129486\127995\8205\9792\65039"+ , "\129486\127995\8205\9792\65039\8205\10145\65039" , "\129486\127995\8205\9794\65039"+ , "\129486\127995\8205\9794\65039\8205\10145\65039" , "\129486\127996\8205\9792\65039"+ , "\129486\127996\8205\9792\65039\8205\10145\65039" , "\129486\127996\8205\9794\65039"+ , "\129486\127996\8205\9794\65039\8205\10145\65039" , "\129486\127997\8205\9792\65039"+ , "\129486\127997\8205\9792\65039\8205\10145\65039" , "\129486\127997\8205\9794\65039"+ , "\129486\127997\8205\9794\65039\8205\10145\65039" , "\129486\127998\8205\9792\65039"+ , "\129486\127998\8205\9792\65039\8205\10145\65039" , "\129486\127998\8205\9794\65039"+ , "\129486\127998\8205\9794\65039\8205\10145\65039" , "\129486\127999\8205\9792\65039"+ , "\129486\127999\8205\9792\65039\8205\10145\65039" , "\129486\127999\8205\9794\65039"+ , "\129486\127999\8205\9794\65039\8205\10145\65039" , "\129487\8205\9792\65039" , "\129487\8205\9794\65039" , "\129487\127995\8205\9792\65039"@@ -5600,18 +5713,23 @@ , "\129489\127999\8205\129457" , "\129489\127999\8205\129458" , "\129489\127999\8205\129459"+ , "\9939\65039\8205\128165" , "\10084\65039\8205\128293" , "\10084\65039\8205\129657"+ , "\127812\8205\129003"+ , "\127819\8205\129001" , "\127987\65039\8205\9895\65039" , "\127987\65039\8205\127752" , "\127988\8205\9760\65039" , "\128008\8205\11035" , "\128021\8205\129466" , "\128038\8205\11035"+ , "\128038\8205\128293" , "\128059\8205\10052\65039" , "\128065\65039\8205\128488\65039" , "\128558\8205\128168" , "\128565\8205\128171" , "\128566\8205\127787\65039"- , "\129489\8205\127876"+ , "\128578\8205\8596\65039"+ , "\128578\8205\8597\65039" ]
+ src/Trie.hs view
@@ -0,0 +1,83 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE StrictData #-}+module Trie+ ( Trie+ , empty+ , insert+ , alter+ , unfoldTrie+ , fromList+ , matchLongestPrefix+ )+ where++import Control.Monad (foldM)+import qualified Data.IntMap as M+import Data.Bifunctor (first)+import Data.Maybe (fromMaybe)++data Trie a = Trie (Maybe a) (Maybe (M.IntMap (Trie a)))+ deriving (Show, Eq, Ord)++instance Semigroup (Trie a) where+ trie1 <> trie2 = foldr (uncurry insert) trie1 (unfoldTrie trie2)++instance Monoid (Trie a) where+ mempty = Trie Nothing Nothing+ mappend = (<>)++empty :: Trie a+empty = Trie Nothing Nothing++unfoldTrie :: Trie a -> [([Int], a)]+unfoldTrie = map (first reverse) . go []+ where+ go xs (Trie (Just v) (Just m)) =+ (xs, v) : concatMap (gopair xs) (M.toList m)+ go xs (Trie (Just v) Nothing) = [(xs, v)]+ go xs (Trie Nothing (Just m)) =+ concatMap (gopair xs) (M.toList m)+ go _ (Trie Nothing Nothing) = []+ gopair xs (i, trie) = go (i:xs) trie++insert :: [Int] -> a -> Trie a -> Trie a+insert [] x (Trie _ mbm) = Trie (Just x) mbm+insert (c:cs) x (Trie mbv (Just m)) =+ case M.lookup c m of+ Nothing -> Trie mbv (Just (M.insert c (insert cs x empty) m))+ Just trie -> Trie mbv (Just (M.insert c (insert cs x trie) m))+insert (c:cs) x (Trie mbv Nothing) =+ Trie mbv (Just (M.insert c (insert cs x empty) mempty))++fromList :: [([Int], a)] -> Trie a+fromList = foldr (uncurry insert) mempty++alter :: (Maybe a -> Maybe a) -> [Int] -> Trie a -> Trie a+alter f [] (Trie mbv mbm) = Trie (f mbv) mbm+alter f (c:cs) (Trie mbv (Just m)) =+ Trie mbv (Just (M.insert c (alter f cs $ fromMaybe empty $ M.lookup c m) m))+alter f (c:cs) (Trie mbv Nothing) =+ Trie mbv (Just (M.insert c (alter f cs empty) mempty))++type MatchState a = (Maybe (a, Int, Trie a), Int, Trie a)+ -- best match so far, number of code points consumed, current subtrie++{-# SPECIALIZE matchLongestPrefix :: Trie a -> [Int] -> Maybe (a, Int, Trie a) #-}+-- returns Nothing for no match, or:+-- Just (value, number of code points consumed, subtrie)+matchLongestPrefix :: Foldable t => Trie a -> t Int -> Maybe (a, Int, Trie a)+matchLongestPrefix trie = either id getBest . foldM go (Nothing, 0, trie)+ where+ getBest (x,_,_) = x+ -- Left means we've failed, Right means we're still pursuing a match+ go :: MatchState a -> Int -> Either (Maybe (a, Int, Trie a)) (MatchState a)+ go (best, consumed, Trie _ mbm) c =+ case mbm >>= M.lookup c of+ -- char not matched: stop processing, return best so far:+ Nothing -> Left best+ -- char matched, with value: replace best, keep going:+ Just subtrie@(Trie (Just x) _)+ -> Right (Just (x, consumed + 1, subtrie), consumed + 1, subtrie)+ -- char matched, but not value: keep best, keep going:+ Just subtrie@(Trie Nothing _)+ -> Right (best, consumed + 1, subtrie)
test/test.hs view
@@ -14,4 +14,8 @@ , assertEqual "emoji name from nonexistent" Nothing (emojiFromAlias "saotehusatnoeus") , assertEqual "aliases from nonexistent emoji" Nothing (aliasesFromEmoji "oo") , assertEqual "aliases from emoji" (Just ["rage", "pout"]) (aliasesFromEmoji "😡")+ , assertEqual "replaced emojis" "myα→ rage(😡) is 100(💯)"+ (replaceEmojis (\txt aliases -> case aliases of+ [] -> txt+ (a:_) -> a <> "(" <> txt <> ")") "myα→ 😡 is 💯") ]