2016-09-30 43 views
5

Parametrelerden birinin daha iyi bir tür (* -> *) olduğu bir polimorfik türüm var.Yüksek kinder tipi değişkenlerle türetme

data Tricky m = Tricky { numbers :: m Int, genesis :: m String } 

Arcane ve güvensiz dil uzantıları kullanmadan bu tür örneklerin örneklerini elde etmenin genel bir yolu var mı?

deriving instance Show (m Int) => Show (Tricky m) 

Ama GHC sonra örneği kafasına daha küçük olması kısıtlaması şikayet etmekte ve UndecidableInstances yönünde beni işaret:

ben bağlamı belirtmek diye StandaloneDeriving sağlayan çalıştı.

Özetlemek gerekirse:

1. Ben sadece bu tavsiye ile birlikte gitmeli, ya da daha iyi bir yolu vardır?

2. Bu işlemi kolaylaştırmak için herhangi bir öneriniz var mı?

3. Bir şekilde 'yüksek nazlı' örnekleri türetmek isteyen bir yanlış yöne mi? o UndecidableInstances hakkında güvensiz bir şey yok yerine birkaç beton türleri (örn. Vector, [], Set)

cevap

8

1. için örneklerini türetmek için daha iyi olurdu. gereksinimlerini karşılaması gereken Show (Tricky m) tanımlamanın başka bir yolu vardır. Bu

class Show1 f where 
    showsPrec1 :: Show a => Int -> f a -> ShowS 

Bir even cleverer version of Show1 gibi typeclass tarafından yakalanır 4,9 dayandırmak eklendi. a'un Show a örneğinin olmaması durumunda m a gösterilebilmesi için daha geneldir.

2. Bunu yapmak için doğru bitleri ve parçaları buldunuz.

3. Hayır, doğru başlı Vector, [] ve Set gibi daha da yüksek-kinded yapıları üzerindeki soyut içelim. Monad transformatörleri, (* -> *) -> (* -> *) türüne ve bir functor gibi aynı tipte tipler üretmek için bir tür functor ile aynı tür (* -> *) türlerine sahiptir. Tricky, (* -> *) -> * türüne sahiptir, bir functor ile aynı türden bir şey alır ve sıradan bir veri tipi üretir. Bu tür veri türlerini "Modeller" olarak adlandırıyorum çünkü bunlar nasıl bir araya getirildiğine dair bir veri türü oluşturuyorlar.