Non-injective functions and URL slugs - Haskell

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Sridhar Ratnakumar

So I began writing this:

-- | Make a non-injective function injective
mkInjective :: [a] -> (a -> b) -> a -> b
mkInjective domain f = undefined
Sridhar Ratnakumar

Final implementation:

-- | Make a non-injective function injective
mkInjective :: Ord b => [a] -> (a -> b) -> a -> (b, Maybe a)
mkInjective domain f =
  let image = map f domain
      nonInjectiveImage = Set.fromList $ dups image
   in \a ->
        let b = f a
         in if Set.member b nonInjectiveImage
              then (b, Just a)
              else (b, Nothing)
  where
    dups = Map.keys . Map.filter (> 1) . Map.fromListWith (+) . fmap (,1 :: Int)

Guess what it is used for.

Sridhar Ratnakumar

Entirely thing has been put in the Web.UniqSlug module: https://github.com/srid/zulip-archive/blob/master/src/Web/UniqSlug.hs

Zulip Archive viewer (statically generated HTML). Contribute to srid/zulip-archive development by creating an account on GitHub.
Sridhar Ratnakumar

See it in action here. https://funprog.srid.ca/general/ Note that almost all topics have "clean URLs" (matching topic title), except for two topics titled "Interface". They differ only case of the first letter, so their URL slug has a md5 hash appended to it.