#! /usr/bin/env nix-shell #! nix-shell -i ghci shell.nix -- Type indexed nested Eithers {-# LANGUAGE TypeOperators #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeSynonymInstances #-} type (:||:) = Either infixr 1 :||: class Contains h n where extract :: h -> Maybe n insert :: n -> h instance Contains (a :||: b) a where extract (Left a) = Just a extract _ = Nothing insert = Left instance Contains (a :||: b) b where extract (Right a) = Just a extract _ = Nothing insert = Right instance {-# OVERLAPS #-} Contains h n => Contains (a :||: h) n where extract (Right a) = extract a extract _ = Nothing insert = Right . insert test :: Maybe String test = extract (insert "test" :: String :||: Integer :||: Float)