content: {-# LANGUAGE FlexibleInstances, GADTs, MultiParamTypeClasses,
    FlexibleContexts, IncoherentInstances, LambdaCase, DataKinds #-}
  -- Note on IncoherentInstances: the two instances below will both work fine
  -- for `GeneralizeSignal Void Void`. They should never be called.
  module React.Local (GeneralizeSignal(..), locally) where
  
  import Control.Applicative
  import Data.Void
  
  import React.Types
  
  
  -- |
  -- Implement when a local signal can be generalized to a higher level one. Used
  -- by 'locally'
  class GeneralizeSignal sigloc siggen where
      generalizeSignal :: sigloc -> siggen
  
  
  instance GeneralizeSignal a a where
      generalizeSignal = id
  
  
  instance GeneralizeSignal Void a where
      generalizeSignal = absurd
  
  
  -- |
  -- 'locally' exists to make it simple to embed classes with local concerns. An
  -- example will be helpful:
  --
  -- We have some page which can respond to many different events.
  --
  -- @
  -- data Transition
  --     = UserTyping JSString
  --     | Toggle
  --     ...
  --
  -- globalPage_ :: [AttrOrHandler Transition] -> ReactNode Transition
  -- @
  --
  -- And we want to be able to embed some components that don't care about all
  -- that. 'inputBox_' can only output 'JSString' and 'pageHeader_' can't send
  -- any signals at all.
  --
  -- @
  -- inputBox_ :: ReactNode JSString
  -- pageHeader_ :: ReactNode Void
  -- @
  --
  -- With locally we can easily embed them in 'globalPage_':
  --
  -- @
  -- instance GeneralizeSignal JSString Transition where
  --     generalizeSignal = UserTyping
  --
  -- -- (globalPage_)
  -- renderFn = \props state -> div_ [ class_ "global-page" ] $ do
  --     locally pageHeader_
  --     ...
  --     locally inputBox_
  --     ...
  -- @
  locally :: GeneralizeSignal sigloc siggen
          => ReactNode sigloc
          -> ReactNode siggen
  locally = LocalNode generalizeSignal
  