I do not think this is possible with the current GADT if you are not able to have a partially defined function. You can write
but you cannot make this function final because you will need
| otherwise = L a
and this is not typical, since you just proved that L a :: Tree a and L x :: Tree x are different types.
However, if you define GADT as existentially quantified
data Tree where N :: (O abc) -> Tree -> Tree -> Tree L :: Typeable a => a -> Tree f :: Typeable a => a -> Tree -> Tree fx (L a) | show (typeOf x) == show (typeOf a) = L x | otherwise = L a
you lose type information in your Tree , but it is typechecks and is complete
another version that stores type information
data Tree abc where N :: (O abc) -> Tree abc -> Tree abc -> Tree abc L :: Typeable a => a -> Tree abc f :: Typeable a => a -> Tree abc -> Tree abc fx (L a) | show (typeOf x) == show (typeOf a) = L x | otherwise = L a
here you save type information for any possible value stored in L in the type Tree . This might work if you only need a few different types, but get cumbersome quickly.
source share