{-# LANGUAGE DeriveAnyClass, DeriveGeneric, LambdaCase #-} {-| -} module Enumerate.Function.Example where import Enumerate.Types import Enumerate.Function.Extra import Enumerate.Function {- stack build && stack exec -- enumerate-function-example -} main = do putStrLn "\nenumerating domain...\n" traverse_ print (enumerated :: [Edit]) putStrLn "\nserializing function...\n" putStrLn $ displayFunction emacsEdit putStrLn "\nserializing inverse...\n" traverse_ putStrLn $ displayInjective emacsEdit putStrLn "\ndetecting jectivity..." case isInjective emacsEdit of Nothing -> print $ "`emacsEdit` is non-injective" Just fromKeyBinding -> do putStrLn $ "`emacsEdit` is injective:\n" let aKeyBinding = ["C-","M-b","C-w"] let anEdit = fromKeyBinding aKeyBinding putStrLn $ intercalate " " ["", show aKeyBinding, "<-", show anEdit] -- no instance (Enumerable KeyBinding) -- case isSurjective emacsEdit of -- Nothing -> do -- print $ "`emacsEdit` is non-surjective (there are infinitely many strings)" -- Just fromKeyBinding -> do -- putStrLn $ "`emacsEdit` is surjective:\n" data Edit = Edit Action Slice Region deriving (Show,Read,Eq,Ord,Generic,Enumerable) data Action = Cut | Delete | Transpose deriving (Show,Read,Eq,Ord,Enum,Bounded,Generic,Enumerable) data Slice = Whole | Backwards | Forwards deriving (Show,Read,Eq,Ord,Enum,Bounded,Generic,Enumerable) data Region = Character | Token | Line deriving (Show,Read,Eq,Ord,Enum,Bounded,Generic,Enumerable) type KeyBinding = [String] emacsEdit :: Edit -> KeyBinding emacsEdit = \case Edit Transpose _ region -> emacsTranspose region Edit Cut slice region -> emacsSelect region slice ++ ["C-w"] Edit Delete slice region -> emacsSelect region slice ++ [""] emacsTranspose :: Region -> KeyBinding emacsTranspose = \case Character -> ["C-t"] Token -> ["M-t"] Line -> ["C-x-t"] emacsSelect :: Region -> Slice -> KeyBinding emacsSelect region = \case Whole -> emacsBeginRegion region ++ emacsMark ++ emacsEndRegion region Backwards -> emacsMark ++ emacsBeginRegion region Forwards -> emacsMark ++ emacsEndRegion region where emacsMark = ["C-"] emacsBeginRegion :: Region -> KeyBinding emacsBeginRegion = \case Character -> [""] Token -> ["M-b"] Line -> ["C-a"] emacsEndRegion :: Region -> KeyBinding emacsEndRegion = \case Character -> [""] Token -> ["M-f"] Line -> ["C-e"] -- chromeEdit :: Partial Edit KeyBinding -- chromeEdit = maybe2throw <<< \case -- Edit Transpose _ region -> Nothing -- Edit Cut slice region -> chromeSelect region slice ++ ["M-c"] -- Edit Delete slice region -> chromeSelect region slice ++ [""]