This shall work generally, and a link to the implementation of monads in this approach: https://github.com/purescript/purescript/issues/3067#issuecomment-583290319 .
class Implicit label i | label -> i where
inst :: label -> i
data EqD = EqD
data Eq a = Eq {
eq :: a -> a -> Boolean
, ne :: a -> a -> Boolean
}
mkEqFromEq :: forall a. {eq :: a -> a -> Boolean} -> Eq a
mkEqFromEq {eq} = Eq {eq: eq, ne: \x y -> not $ eq x y }
mkEqFromNEq :: forall a. {ne :: a -> a -> Boolean} -> Eq a
mkEqFromNEq {ne} = Eq {ne: ne, eq: \x y -> not $ ne x y}
-- EDIT:
eq' = r.eq where Eq r = inst EqD
infixl 2 eq' as ===
instance eqInt :: Implicit EqD (Eq Int) where
inst _ = mkEqFromEq { eq : (==) }
main :: Effect Unit
main = do
log $ show (1 === 2) -- false
log $ show (3 === 3) -- true