My aim is to eliminate () from terms, like this:
(a, b) -> (a, b)
((), b) -> b
(a, ((), b)) -> (a, b)
...
And this is the code:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Simplify where
import Data.Type.Bool
import Data.Type.Equality
type family Simplify x where
Simplify (op () x) = Simplify x
Simplify (op x ()) = Simplify x
Simplify (op x y) = If (x == Simplify x && y == Simplify y)
(op x y)
(Simplify (op (Simplify x) (Simplify y)))
Simplify x = x
However, trying it out:
:kind! Simplify (String, Int)
...leads to an infinite loop in the type checker. I'm thinking the If type family should be taking care of irreducible terms, but I'm obviously missing something. But what?
Ifwon't be evaluated unless it is needed. I think that assumption is unwarranted. - Daniel Wagneropis probably wrong. For example,Simplify (Either () Int)probably should not reduce toInt. - Daniel Wagner(String, (), Int)? Both solutions suggested so far reduce that toInt. I don't even know if it's possible to get(String, Int). - gallais