From 426c931d5b0ebc6d53396c34ec38eb342be501c3 Mon Sep 17 00:00:00 2001 From: jao Date: Sun, 25 Nov 2018 07:35:54 +0000 Subject: Refactoring: Xmobar.Run --- src/lib/Xmobar/Run/Runnable.hs | 60 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/lib/Xmobar/Run/Runnable.hs (limited to 'src/lib/Xmobar/Run/Runnable.hs') diff --git a/src/lib/Xmobar/Run/Runnable.hs b/src/lib/Xmobar/Run/Runnable.hs new file mode 100644 index 0000000..962166e --- /dev/null +++ b/src/lib/Xmobar/Run/Runnable.hs @@ -0,0 +1,60 @@ +{-# LANGUAGE ExistentialQuantification, MultiParamTypeClasses, FlexibleContexts, FlexibleInstances #-} +----------------------------------------------------------------------------- +-- | +-- Module : Xmobar.Runnable +-- Copyright : (c) Andrea Rossato +-- License : BSD-style (see LICENSE) +-- +-- Maintainer : Jose A. Ortega Ruiz +-- Stability : unstable +-- Portability : unportable +-- +-- The existential type to store the list of commands to be executed. +-- I must thank Claus Reinke for the help in understanding the mysteries of +-- reading existential types. The Read instance of Runnable must be credited to +-- him. +-- +-- See here: +-- http:\/\/www.haskell.org\/pipermail\/haskell-cafe\/2007-July\/028227.html +-- +----------------------------------------------------------------------------- + +module Xmobar.Run.Runnable where + +import Control.Monad +import Text.Read +import Xmobar.Run.Types (runnableTypes) +import Xmobar.Run.Commands + +data Runnable = forall r . (Exec r, Read r, Show r) => Run r + +instance Exec Runnable where + start (Run a) = start a + alias (Run a) = alias a + trigger (Run a) = trigger a + +instance Show Runnable where + show (Run x) = show x + +instance Read Runnable where + readPrec = readRunnable + +class ReadAsAnyOf ts ex where + -- | Reads an existential type as any of hidden types ts + readAsAnyOf :: ts -> ReadPrec ex + +instance ReadAsAnyOf () ex where + readAsAnyOf ~() = mzero + +instance (Read t, Exec t, ReadAsAnyOf ts Runnable) => ReadAsAnyOf (t,ts) Runnable where + readAsAnyOf ~(t,ts) = r t `mplus` readAsAnyOf ts + where r ty = do { m <- readPrec; return (Run (m `asTypeOf` ty)) } + +-- | The 'Prelude.Read' parser for the 'Runnable' existential type. It +-- needs an 'Prelude.undefined' with a type signature containing the +-- list of all possible types hidden within 'Runnable'. See 'Config.runnableTypes'. +-- Each hidden type must have a 'Prelude.Read' instance. +readRunnable :: ReadPrec Runnable +readRunnable = prec 10 $ do + Ident "Run" <- lexP + parens $ readAsAnyOf runnableTypes -- cgit v1.2.3