content: {-# LANGUAGE DeriveGeneric #-}
  {-# LANGUAGE FlexibleContexts #-}
  {-# LANGUAGE FlexibleInstances #-}
  {-# LANGUAGE UndecidableInstances #-}
  {-# LANGUAGE MultiParamTypeClasses #-}
  {-# LANGUAGE FunctionalDependencies #-}
  {-# LANGUAGE TypeOperators #-}
  {-# LANGUAGE ViewPatterns #-}
  import GHC.Generics
  
  -- from https://ocharles.org.uk/blog/posts/2014-12-16-derive-generic.html
  
  data Valid e a = Error e | OK a
    deriving (Generic)
  
  toEither :: Valid e a -> Either e a
  toEither (Error e) = Left e
  toEither (OK a) = Right a
  
  fromEither :: Either e a -> Valid e a
  fromEither (Left e) = Error e
  fromEither (Right a) = OK a
  
  -- ---------------------------------------------------------------------
  
  class GetError rep e | rep -> e where
    getError' :: rep a -> Maybe e
  
  instance GetError f e => GetError (M1 i c f) e where
    getError' (M1 m1) = getError' m1
  
  instance GetError l e => GetError (l :+: r) e where
    getError' (L1 l) = getError' l
    getError' (R1 _) = Nothing
  
  instance GetError (K1 i e) e where
    getError' (K1 e) = Just e
  
  getError :: (Generic (errorLike e a), GetError (Rep (errorLike e a)) e) => errorLike e a -> Maybe e
  getError = getError' . from
  
  