Рассмотрим следующее определение HList
:
infixr 5 :>
data HList (types :: [*]) where
HNil :: HList '[]
(:>) :: a -> HList l -> HList (a:l)
И семейство типов Map
для сопоставления списков уровней типов:
type family Map (f :: * -> *) (xs :: [*]) where
Map f '[] = '[]
Map f (x ': xs) = (f x) ': xs
Теперь я хотел бы определить эквивалентность sequence
для HList
s. Моя попытка выглядит
hSequence :: Applicative m => HList (Map m ins) -> m (HList ins)
hSequence HNil = pure HNil
hSequence (x :> rest) = (:>) <$> x <*> hSequence rest
Но я получаю такие ошибки:
Could not deduce: ins ~ '[]
from the context: Map m ins ~ '[]
bound by a pattern with constructor: HNil :: HList '[]
Для меня это выглядит так, как будто компилятор не уверен, что если Map m
возвращает []
в каком-то списке, то этот список пуст. К сожалению, я не вижу никакого способа убедить его в этом факте. Что мне делать в этой ситуации?
Я использую GHC 8.6.5
со следующими расширениями:
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}