Skip to content

v0.5.0

Choose a tag to compare

@thomashoneyman thomashoneyman released this 16 Mar 05:17

Breaking changes (😱!!!):

  • Add support for PureScript 0.14 and Halogen 6, dropping support for previous versions of the compiler and Halogen. (#71 by @CarstenKoenig, #72 by @thomashoneyman)

  • Move to a single index for hook types. (#32 by @thomashoneyman)

    Using a single index for Hook types simplifies the Hooks implementation and makes defining your own Hooks easier and less confusing. It also allows the library to drop its dependency on indexed-monad.

    Previously, Hooks were defined as an indexed monad with parameters to track the before and after state of a Hook bind:

    -- Old approach
    type Hook m (newHooks :: Type -> Type) a =
      forall hooks. Hooked m hooks (newHooks hooks) a
    
    newtype Hooked m hooks newHooks a =
      Hooked (Indexed (Free (UseHookF m)) hooks newHooks a)
    
    bind
      :: forall a b x y z m
      . Hooked m hooks hooks' a
      -> (a -> Hooked m hooks' newHooks b)
      -> Hooked m hooks newHooks b

    Now, Hooks are defined with a custom HookType and each bind produces a new, single index made up of all the hook types in use.

    -- New approach
    data HookType
    
    newtype Hook m (h :: HookType) a = Hook (Free (UseHookF m) a)
    
    foreign import data Hooked :: HookType -> HookType -> HookType
    infixr 1 type Hooked as <>
    
    bind
      :: forall h h' m a b
       . Hook m h a
      -> (a -> Hook m h' b)
      -> Hook m (h <> h') b

    This is a breaking change because it changes how you define your Hook types in Halogen Hooks. First, Hooks are now written in the order they occur.

    -- Assume UseState, then UseEffect, then UseRef in the code
    
    -- Previously: this reads backwards, as state transitions 'away from' the
    -- hooks type variable
    UseRef Int
      (UseEffect
      (UseState Int hooks))
    
    -- Now: this reads in the order hooks are applied in the code, where
    -- `Pure` represents the call to `pure`
    UseState Int
      <> UseEffect
      <> UseRef Int
      <> Hooks.Pure

    Second, you no longer use a newtype to define Hooks. Instead, you'll foreign import a data type to represent your Hook type and use the HookNewtype type class.

    -- Before
    type UseX' hooks = UseState Int (UseEffect hooks)
    
    newtype UseX hooks = UseX (UseX' hooks)
    
    derive instance newtypeUseX :: Newtype (UseX hooks) _
    
    -- After
    type UseX' = UseEffect <> UseState Int <> Hooks.Pure
    
    foreign import data UseX :: Hooks.HookType
    
    instance newtypeUseX :: HookNewtype UseX UseX'

New features:

Bugfixes:

Other improvements:

  • Docs: Added technical documentation that covers the main concepts used in the internal implementation (#59 by @thomashoneyman).
  • Docs: Added a changelog to record changes to the library over time (#62 by @thomashoneyman).
  • Tests: Added performance tests to measure the performance impact of changes (#53 by @thomashoneyman, #56 by @thomashoneyman).
  • Updated the Nix shell to use PureScript 0.14 tooling