Получение последнего элемента разнородного списка - PullRequest
2 голосов
/ 27 мая 2020

Я пытаюсь определить функцию (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 #-} к первому экземпляру решает проблему, но это кажется слишком хакерским решением такой простой проблемы. Есть лучший способ сделать это? Спасибо!

1 Ответ

0 голосов
/ 27 мая 2020

Предполагая, что HList определен как GADT, вам в первую очередь не нужен класс типа.

data HList xs where
  HCons :: x -> HList xs -> HList (x ': xs)
  HNil :: HList '[]

type family HLastR xs where
  HLastR '[x] = x
  HLastR (x ': xs) = HLastR xs

hlast :: HList xs -> HLastR xs
hlast (HCons x HNil) = x
hlast (HCons _ xs@(HCons _ _)) = hlast xs
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...