Haskell fonksiyonunu daha yüksek mertebeden bir lambda hesaplaması kodlamasında kaldırmak istiyorum. Bu, Oleg'in Typed Tagless Final kodlamasından neredeyse aynı şekilde alınmıştır.Genelleştirilmiş çok parametreli fonksiyon kaldırma için tipik numaralar
class Lam r where
emb :: a -> r a
(^) :: r (r a -> r a) -> (r a -> r a)
lam :: (r a -> r a) -> r (r a -> r a)
instance Lam Identity where
emb = Identity
f^x = f >>= ($ x)
lam f = return (f . return =<<) -- call-by-value
eval = runIdentity
Ben emb
kullanarak Lam
içine keyfi Haskell türlerini gömebilirsiniz ama sonra uygulama için (^)
kullanamazsınız. Ayrıca, kaldırılmış fonksiyonlar tembel davranırdı. Bunun yerine, uygulamayı uygulamaya göre kaldırmak zorundayım.
emb1 :: (Applicative r, Lam r)
=> (a -> b) -> r (r a -> r b)
emb1 f = lam $ \ra -> f <$> ra
emb2 :: (Applicative r, Lam r)
=> (a -> b -> c) -> r (r a -> r (r b -> r c))
emb2 f = lam $ \ra -> lam $ \rb -> f <$> ra <*> rb
emb3 :: (Applicative r, Lam r)
=> (a -> b -> c -> d)
-> r (r a -> r (r b -> r (r c -> r d)))
emb3 f = lam $ \ra -> lam $ \rb -> lam $ \rc -> f <$> ra <*> rb <*> rc
>>> eval $ emb2 (+)^emb 1^emb 2
3
Bu bir çok boilerplate var. Herhangi bir işlev için çalışacak genel bir kaldırma işlevi oluşturmak istiyorum. Printf
'un PrintfType
veya fixed-vector
'ların Cont
türlerine benzer bir şey kullanmanın mümkün olabileceğini hissediyorum. Ben türü işlevleri
type family Low h o
type instance Low () o = o
type instance Low (a, h) o = a -> Low h o
type family Lift r h o
type instance Lift r() o = o
type instance Lift r (a, h) o = r a -> r (Lift r h o)
class Emb r h o where
embed :: Low h o -> r (Lift r h o)
instance (Lam r) => Emb r() o where
embed = emb
instance (Lam r, Applicative r, Emb r h o) => Emb r (a, h) o where
embed = ?
kullanarak istediğiniz Ama çok genellikle nedeniyle birebirlik sorunları nedeniyle, bu yöntemle takılıp neler belirtebilirsiniz. Yeni tip sarmalayıcılar ve kapsamlı değişkenler arasında gerçekten iğrenç bir kombinasyonla enjeksiyonu çözebildim, ancak aslında hiçbir zaman yazılmadı.
Bu Haskell'de ifade etmek mümkün mü?
Cevabı bilmiyorum, ancak bir sonraki bağlantı yararlı olabilir: http://hackage.haskell.org/package/layers-0.1/docs/Documentation-Layers-Overview.html – wit