Serbest değişkenleri tarafından parametrelendirilen lambda terimleri için bu gösterimi düşünün. (Bellegarde ve Hook 1994, Bird ve Paterson 1999, Altenkirch ve Reus 1999'un makalelerine bakın.)
data Tm a = Var a
| Tm a :$ Tm a
| Lam (Tm (Maybe a))
Bunu kesinlikle Functoryeniden adlandırma Monadfikrini ve ikame kavramını yakalayan bir hale getirebilirsiniz .
instance Functor Tm where
fmap rho (Var a) = Var (rho a)
fmap rho (f :$ s) = fmap rho f :$ fmap rho s
fmap rho (Lam t) = Lam (fmap (fmap rho) t)
instance Monad Tm where
return = Var
Var a >>= sig = sig a
(f :$ s) >>= sig = (f >>= sig) :$ (s >>= sig)
Lam t >>= sig = Lam (t >>= maybe (Var Nothing) (fmap Just . sig))
Şimdi kapalı şartları düşünün : bunlar sakinleridir Tm Void. Kapalı terimleri rastgele serbest değişkenler içeren terimlere yerleştirebilmelisiniz. Nasıl?
fmap absurd :: Tm Void -> Tm a
İşin püf noktası, elbette, bu işlevin hiçbir şey yapmadan terimi aşacak olmasıdır. Ama daha dürüst bir dokunuş unsafeCoerce. Ve bu yüzden vacuouseklendi Data.Void...
Veya bir değerlendirici yazın. Serbest değişkenli değerler burada b.
data Val b
= b :$$ [Val b]
| forall a. LV (a -> Val b) (Tm (Maybe a))
Lambdaları kapanışlar olarak temsil ettim. Değerlendirici, serbest değişkenleri aüzerinden değerlere eşleyen bir ortam tarafından parametrelendirilir b.
eval :: (a -> Val b) -> Tm a -> Val b
eval g (Var a) = g a
eval g (f :$ s) = eval g f $$ eval g s where
(b :$$ vs) $$ v = b :$$ (vs ++ [v])
LV g t $$ v = eval (maybe v g) t
eval g (Lam t) = LV g t
Tahmin ettin. Herhangi bir hedefte kapalı bir terimi değerlendirmek için
eval absurd :: Tm Void -> Val b
Daha genel olarak, Voidnadiren kendi başına kullanılır, ancak bir çeşit imkansızlığı gösteren bir şekilde bir tür parametresini somutlaştırmak istediğinizde kullanışlıdır (örneğin burada, kapalı bir terimde serbest bir değişken kullanarak). Genellikle bu parametrized tipleri daha yüksek dereceden fonksiyonlar bütün türüne operasyonlara parametrelere kaldırma işlemlerindeki ile gelen (örneğin, burada, fmap, >>=, eval). Yani absurdgenel amaçlı operasyon olarak geçiyorsunuz Void.
Başka bir örnek için, Either e vsize bir vtür istisnası getirebileceğini umduğumuz hesaplamaları yakalamak için kullanmayı hayal edin e. Kötü davranış riskini aynı şekilde belgelemek için bu yaklaşımı kullanabilirsiniz. Gayet iyi bu ayarda hesaplamaları davranmış için almak eolmaya Voidardından kullanımını
either absurd id :: Either Void v -> v
güvenle koşmak veya
either absurd Right :: Either Void v -> Either e v
güvenli bileşenleri güvenli olmayan bir dünyaya yerleştirmek.
Oh, ve son bir ani bir "olamaz" ı ele almak. İmlecin olamayacağı her yerde jenerik fermuar yapısında ortaya çıkıyor.
class Differentiable f where
type D f :: * -> *
plug :: (D f x, x) -> f x
newtype K a x = K a
newtype I x = I x
data (f :+: g) x = L (f x)
| R (g x)
data (f :*: g) x = f x :&: g x
instance Differentiable (K a) where
type D (K a) = K Void
plug (K v, x) = absurd v
Tam olarak alakalı olmasa da geri kalanını silmemeye karar verdim.
instance Differentiable I where
type D I = K ()
plug (K (), x) = I x
instance (Differentiable f, Differentiable g) => Differentiable (f :+: g) where
type D (f :+: g) = D f :+: D g
plug (L df, x) = L (plug (df, x))
plug (R dg, x) = R (plug (dg, x))
instance (Differentiable f, Differentiable g) => Differentiable (f :*: g) where
type D (f :*: g) = (D f :*: g) :+: (f :*: D g)
plug (L (df :&: g), x) = plug (df, x) :&: g
plug (R (f :&: dg), x) = f :&: plug (dg, x)
Aslında, belki alakalı. Kendinizi maceraperest hissediyorsanız, bu bitmemiş makale , Voidterimlerin temsilini serbest değişkenlerle nasıl sıkıştıracağınızı gösterir.
data Term f x = Var x | Con (f (Term f x))
a Differentiableand Traversablefunctor'dan serbestçe üretilen herhangi bir sözdiziminde f. Kullandığımız Term f Voidserbest değişkenlerle bölgeleri temsil etmek ve [D f (Term f Void)]göstermek için boruları izole edilmiş bir serbest değişkene, ya da iki ya da daha fazla serbest değişkenlere yollarında bir birleşme ya serbest değişkenlerle bölgeleri ile tünel. Bu makaleyi bir ara bitirmelisin.
Değeri olmayan bir tür için (veya en azından kibar bir şirkette konuşmaya değmez), Voidoldukça kullanışlıdır. Ve absurdbunu nasıl kullandığın.
absurdişlevin bu makaledeContmonad ile ilgili olarak kullanıldığını gösteriyor : haskellforall.com/2012/12/the-continuation-monad.html