Bu, eş anlamlı yazımlarla gerçekten güvenilir bir şekilde yapılamıyor. Varoluşsal türlere veya sıra-n türlerine ihtiyacınız var. Sorun, Haskell'in tip eşanlamlılarının tamamen intersubstitutable olmasına izin vermesidir. Yani, type Baz a b = Foo p a b
'u tanımladığınızda, Foo p a b
'un bulunduğu her bağlamda, Baz a b
'u kullanmanıza izin vermiş olursunuz ve bunun tersi de geçerlidir. Eğer bu tip bir işlevi olsaydı Yani, örneğin:
f1 :: Foo Something a b -> Whatever Something b a
Sonra nedeniyle ikame edilebilirlik, bu aynı tip olurdu:
f1 :: Baz a b -> Whatever Something b a
Ve bu şekilde:
f1 :: Foo p a b -> Whatever Something b a
o zaman bu kadar uzmanlaşmak olabilir
...:
f1 :: Foo SomethingElse a b -> Whatever Something b a
Peki, ne yapabilirsin? Eğer gidebiliriz
{-# LANGUAGE GADTs #-}
data Baz a b where
Baz :: Foo p a b -> Baz a b
İkinci yol: rütbe-n türleri ve devamı-pas stili:
aynı şeyi yapmanın
{-# LANGUAGE ExistentialTypes #-}
data Baz a b = forall p. Baz (Foo p a b)
Alternatif yol: Tek bir varoluş sarıcı türü tanımlamaktır
{-# LANGUAGE RankNTypes #-}
-- To consume one of these, you pass a "callback" function to `runBaz`,
-- which is not allowed to restrict the type variable `p`.
newtype Baz a b = Baz { runBaz :: forall p r. (Foo p a b -> r) -> r }
makeBaz :: Foo p a -> Baz a b
makeBaz foo = Baz ($foo)
Denemeye çalıştığınız ve (söylendiği gibi) çok iyi çalışmadığınız üçüncü yol: tür eş anlamlılar + müstehcen türler (tür argümanları olarak gerçekleşmesi için forall
eş anlamlılarını almak gerekir) Çoğu durumda).
Bence bu tür bir davranış arıyorsunuz (http://www.reddit.com/r/haskell/comments/32k1eu/new_in_ghc_710_partial_type_signatures/cqbxmra), ancak şu anda desteklenmiyor. – rampion