aboutsummaryrefslogtreecommitdiff
path: root/src/Rahm/Desktop/Layout/ReinterpretMessage.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Rahm/Desktop/Layout/ReinterpretMessage.hs')
-rw-r--r--src/Rahm/Desktop/Layout/ReinterpretMessage.hs48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/Rahm/Desktop/Layout/ReinterpretMessage.hs b/src/Rahm/Desktop/Layout/ReinterpretMessage.hs
new file mode 100644
index 0000000..98bf779
--- /dev/null
+++ b/src/Rahm/Desktop/Layout/ReinterpretMessage.hs
@@ -0,0 +1,48 @@
+module Rahm.Desktop.Layout.ReinterpretMessage where
+
+import XMonad (SomeMessage, X)
+import XMonad.Layout.LayoutModifier (LayoutModifier(..))
+import Data.Proxy (Proxy (..))
+
+-- This is a type class that defines how to reinterpret a message. One can think
+-- of this as a kind of type-level function. It lets one associate a function
+-- (reinterpretMessage) with a type construct, which for the case below is a
+-- Symbol.
+--
+-- It would be nice to attach this function to the LayoutModifier directly as a
+-- value, however LayoutModifiers must be Show-able and Read-able and functions
+-- are not. However encoding in the typesystem itsef which function is to be
+-- called is the best alternative I have.
+class DoReinterpret (k :: t) where
+ reinterpretMessage ::
+ Proxy k -> SomeMessage -> X (Maybe SomeMessage)
+
+-- Data construct for association a DoReinterpret function with a concrete
+-- construct that can be used in the LayoutModifier instance.
+--
+-- It wolud be nice to have ReinterpretMessage hold the function as a value
+-- rather than delegate to this kind-instance, however, it won't work because
+-- LayoutModifiers have to be Read-able and Show-able, and functions are neither
+-- of those, so a value-level function may not be a member of a LayoutModifier,
+-- thus I have to settle for delegating to a hard-coded instance using
+-- type-classes.
+data ReinterpretMessage k a = ReinterpretMessage
+ deriving (Show, Read)
+
+-- Instance for ReinterpretMessage as a Layout modifier.
+instance (DoReinterpret k) =>
+ LayoutModifier (ReinterpretMessage k) a where
+
+ handleMessOrMaybeModifyIt self message = do
+
+ -- Delegates to the reinterpretMessage function associatied with the
+ -- type-variable k.
+ newMessage <- reinterpretMessage (ofProxy self) message
+ case newMessage of
+ Just m -> return $ Just $ Right m
+ Nothing -> return $ Just $ Left self
+ where
+ -- ofProxy just provides reifies the phantom type k so the type system can
+ -- figure out what instance to go to.
+ ofProxy :: ReinterpretMessage k a -> Proxy k
+ ofProxy _ = Proxy