Я пытаюсь написать семейство типов, которое я могу использовать для ограничения элементов списка типов типов. У меня есть этот код:Ограничить элементы списка типов в Haskell
{-# LANGUAGE PolyKinds, DataKinds, TypeOperators, TypeFamilies #-}
import GHC.TypeLits (KnownSymbol, symbolVal)
import GHC.Exts (Constraint)
import Data.Proxy (Proxy(..))
type family AllHave (c :: k -> Constraint) (xs :: [k]) :: Constraint
type instance AllHave c '[] =()
type instance AllHave c (x ': xs) = (c x, AllHave c xs)
type family Head (xs :: [k]) :: k where
Head (x ': xs) = x
headProxy :: proxy xs -> Proxy (Head xs)
headProxy _ = Proxy
test :: AllHave KnownSymbol xs => proxy xs -> String
test p = symbolVal (headProxy p)
main :: IO()
main = putStrLn $ test (Proxy :: Proxy '["a", "b"])
Из того, что я понимаю, что это должно работать, но когда я компилирую GHC выплевывает это:
Test.hs:18:10:
Could not deduce (KnownSymbol (Head xs))
arising from a use of ‘symbolVal’
from the context (AllHave KnownSymbol xs)
bound by the type signature for
test :: AllHave KnownSymbol xs => proxy xs -> String
at Test.hs:17:9-52
In the expression: symbolVal (headProxy p)
In an equation for ‘test’: test p = symbolVal (headProxy p)
Спасибо! В этом есть смысл. В качестве последующего вопроса - как бы это выглядело, если бы я хотел предоставить базовый пример для пустых 'xs' и определить' test' рекурсивно по всему списку, а не только по голове? – Nol