Я пытаюсь определить функцию (hLast
), которая возвращает последний элемент гетерогенного списка:
type family HLastR xs where
HLastR '[x] = x
HLastR (x ': xs) = HLastR xs
class HLast xs where
hLast :: HList xs -> HLastR xs
instance HLast '[x] where
hLast (x `HCons` HNil) = x
instance (HLast xs, HLastR xs ~ HLastR (x ': xs)) => HLast (x ': xs) where
hLast (x `HCons` xs) = hLast xs
В этом коде GH C всегда жалуется, что есть перекрывающиеся экземпляры для HLast
. Я не понимаю, как экземпляры могут когда-либо перекрываться: HList
из более чем одного элемента соответствует только второму экземпляру, а синглтоны должны соответствовать только первому экземпляру, поскольку для второго экземпляра требуется экземпляр HLast
для хвоста (HNil
в одноэлементном случае, для которого нет экземпляра).
Добавление директивы {-# OVERLAPPING #-}
к первому экземпляру решает проблему, но это кажется слишком хакерским решением такой простой проблемы. Есть лучший способ сделать это? Спасибо!