Skip to content

Instantly share code, notes, and snippets.

@frasertweedale
Last active October 20, 2017 04:17
Show Gist options
  • Save frasertweedale/ca33db4aa71344124b65696c67835ca2 to your computer and use it in GitHub Desktop.
Save frasertweedale/ca33db4aa71344124b65696c67835ca2 to your computer and use it in GitHub Desktop.
switching mode phantom
{-# LANGUAGE ScopedTypeVariables #-}
class HasMode a where
mode :: Proxy a -> Mode
instance HasMode 'BrowseMail where
mode _ = BrowseMail
-- | instantiate this class to specify a valid mode transition
class ModeTransition a b where
-- | transition from 'a' to 'a' is no transition at all
-- thus it is vacuously valid!
instance ModeTransition a a where
-- use infix
chain :: Action ctx AppState -> Action ctx a -> Action ctx a
chain (Action d1 f1) (Action d2 f2) =
Action (d1 <> d2) (f1 >=> f2)
-- | Chain two actions, allowing a mode tranisition (if such a transition
-- is defined).
--
chain'
:: forall ctx ctx' a. (HasMode ctx', ModeTranisiton ctx ctx')
=> Action ctx AppState
-> Action ctx' a
-> Action ctx a -- ^ the composed action is in the ORIGINAL context, because that is the starting point!
chain' (Action d1 f1) (Action d2 f2) =
Action (d1 <> d2) (f1 >=> switchMode >=> f2)
where
switchMode = pure . set asAppMode (mode (Proxy :: Proxy ctx'))
-- this action switches to 'SearchMail, then focuses the search widget
--
switchThenFocus :: Action 'BrowseMail (Brick.Next AppState)
switchThenFocus = noop `chain'` (focus :: Action 'SearchMail AppState) `chain` continue
-- an noop action; this just returns the current 'AppState'.
-- This action can be used at the start of action chain where
-- an immediate mode switch is required.
noop :: Action ctx AppState
noop = Action "no-op" pure
@frasertweedale
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment