Mam klasę dla kolejek, która pozwala instancji zdefiniować ograniczenia, które umieszcza na elementach. Na przykład, kolejka priorytet wymaga jego elementy będzie można zamówić:Czy mogę sparametryzować pusty typ ograniczenia?
{-# LANGUAGE MultiParamTypeClasses, ConstraintKinds, FunctionalDependencies #-}
class Queue q c | q -> c where
empty :: q a
qpop :: c a => q a -> Maybe (a, q a)
qpush :: c a => a -> q a -> q a
data PriorityQueue a = ...
instance Queue PriorityQueue Ord where
...
Działa to zaklęcie: wewnątrz deklaracja instancja dla PriorityQueue
mogę operować na elementach kolejki przy użyciu członków Ord
takich jak (>)
.
ja utknąłem próbując określić kolejkę, która stawia żadnych wymagań na jej elementów:
newtype LIFO a = LIFO [a]
instance Queue LIFO() where
empty = LIFO []
qpop (LIFO []) = Nothing
qpop (LIFO (x:xs)) = Just (x, LIFO xs)
qpush x (LIFO xs) = LIFO $ x:xs
zawodzi Ten, z następującym komunikatem o błędzie z GHC:
The second argument of `Queue' should have kind `* -> Constraint',
but `()' has kind `*'
In the instance declaration for `Queue LIFO()'
Ten komunikat o błędzie ma dla mnie sens. Eq
akceptuje parametr typu (zazwyczaj piszemy Eq a => ...
), podczas gdy ()
nie ma parametrów - jest to zwykły stary rodzaj niedopasowania.
miałem pęknięcie na napisanie funkcji typu, który ignoruje swój drugi argument, który pozwoliłby mi pisać instance Queue LIFO (Const())
:
{-# LANGUAGE TypeFamilies, KindSignatures, PolyKinds #-}
type family Const a b :: k -> k2 -> k
type instance Const a b = a
znajdę tę interakcję rodzin typu i polimorfizmu rodzaju bardzo piękne, więc byłem dość rozczarowany, kiedy to nie działa (naprawdę myślałem, że będzie!):
Expecting two more arguments to `a'
The first argument of `Const' should have kind `*',
but `a' has kind `k0 -> k1 -> k0'
In the type `a'
In the type instance declaration for `Const'
mam wrażenie ten ostatni przykład jest coś jak głupi błąd składni (jestem nowy, aby wpisać rodziny). Jak mogę napisać Constraint
, który nie nakłada żadnych ograniczeń na jego argument?
Spróbuj definiowania 'typ rodziny i mech (A :: k1) (B) :: k2 :: k1' następnie' Const (() :: Constraint) 'ma pożądany rodzaj, jednak nadal utknie. –
@ J.Abrahamson Tak, wydaje się utknąć przy deklaracji "instancji": "Nielegalna aplikacja rodziny synonimów w instancji". Dlaczego moja pierwotna próba "Const" zawiodła? –
Możesz być również zainteresowany zrobieniem tego właśnie z 'TypeFamilies'. http://www.skybluetrades.net/blog/posts/2015/03/08/constraint-kinds-associated-types.html – snak