    -- | Haskell project name generation
    -- semi-joke
    module Lambdabot.Plugin.Misc.Fresh (freshPlugin) where

    import Lambdabot.Plugin

    import Control.Monad.Trans
    import Data.Char

    type Fresh = ModuleT Integer LB

    freshPlugin :: Module Integer
    freshPlugin :: Module Integer
    freshPlugin = Module Integer
    forall st. Module st
    newModule
        { moduleDefState = return 0
        , moduleSerialize = Just stdSerial

        , moduleCmds = return
            [ (command "freshname")
                { help = say "freshname. Return a unique Haskell project name."
                , process = \String
    _ -> ModuleT Integer LB String -> Cmd (ModuleT Integer LB) String
    forall (m :: * -> *) a. Monad m => m a -> Cmd m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift ModuleT Integer LB String
    fresh Cmd (ModuleT Integer LB) String
    -> (String -> Cmd (ModuleT Integer LB) ())
    -> Cmd (ModuleT Integer LB) ()
    forall a b.
    Cmd (ModuleT Integer LB) a
    -> (a -> Cmd (ModuleT Integer LB) b) -> Cmd (ModuleT Integer LB) b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= String -> Cmd (ModuleT Integer LB) ()
    forall (m :: * -> *). Monad m => String -> Cmd m ()
    say
                }
            ]
        }

    fresh :: Fresh String
    fresh :: ModuleT Integer LB String
    fresh = (LBState (ModuleT Integer LB)
     -> (LBState (ModuleT Integer LB) -> ModuleT Integer LB ())
     -> ModuleT Integer LB String)
    -> ModuleT Integer LB String
    forall a.
    (LBState (ModuleT Integer LB)
     -> (LBState (ModuleT Integer LB) -> ModuleT Integer LB ())
     -> ModuleT Integer LB a)
    -> ModuleT Integer LB a
    forall (m :: * -> *) a.
    MonadLBState m =>
    (LBState m -> (LBState m -> m ()) -> m a) -> m a
    withMS ((LBState (ModuleT Integer LB)
      -> (LBState (ModuleT Integer LB) -> ModuleT Integer LB ())
      -> ModuleT Integer LB String)
     -> ModuleT Integer LB String)
    -> (LBState (ModuleT Integer LB)
        -> (LBState (ModuleT Integer LB) -> ModuleT Integer LB ())
        -> ModuleT Integer LB String)
    -> ModuleT Integer LB String
    forall a b. (a -> b) -> a -> b
    $ \LBState (ModuleT Integer LB)
    n LBState (ModuleT Integer LB) -> ModuleT Integer LB ()
    f -> do
        LBState (ModuleT Integer LB) -> ModuleT Integer LB ()
    f (Integer
    LBState (ModuleT Integer LB)
    nInteger -> Integer -> Integer
    forall a. Num a => a -> a -> a
    +Integer
    1)
        String -> ModuleT Integer LB String
    forall a. a -> ModuleT Integer LB a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (String
    "Ha" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String -> String
    forall a. [a] -> [a]
    reverse (Integer -> String
    asName Integer
    LBState (ModuleT Integer LB)
    n))

    asName :: Integer -> String
    asName :: Integer -> String
    asName Integer
    i
        | Integer
    i Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Integer
    0    = [Int -> Char
    chr (Char -> Int
    ord Char
    'a')]
        | Integer
    r Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Integer
    0    = [Int -> Char
    chr (Char -> Int
    ord Char
    'a' Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + (Integer -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    a))]
        | Bool
    otherwise =  Int -> Char
    chr (Char -> Int
    ord Char
    'a' Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + (Integer -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    a)) Char -> String -> String
    forall a. a -> [a] -> [a]
    : Integer -> String
    asName Integer
    r
        where
          (Integer
    r,Integer
    a) = Integer
    i Integer -> Integer -> (Integer, Integer)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` Integer
    26