SORU
2 Aralık 2011, Cuma


Nasıl bir değişken variadic bir işlevi alır Haskell bir fonksiyon yazmak

Variadic gibi bir işlevi alır bir işlev oluşturmak için çalışıyorumbir argümanyani

func :: (a -> ... -> a) -> a

bunu nasıl yapabilirim?

polyvariadic functions okudum ve Oleg already did it ancak bir değişken variadic bir işlevi olan bir işlev desen uygulamak için çalışırken kayboldum eminim. Özellikle Olegs yaklaşım glasgow uzantıları ile sadece iş gibi görünüyor ve Çözümü saf Haskell 98 (Text.Printf gibi) çalışmak istiyorum.

Nedenisoruyorum bir argüman olarak boolean bir fonksiyon alır ve gereksiz bir tekrar olup olmadığını kontrol eden bir fonksiyon yapmaya çalışıyorum olduğunu, yani

isTautology :: (Bool -> ... -> Bool) -> Bool

böylece bir tür olabilir:

isTautology (\x -> x && not x)
isTautology (\x y -> x && y || not y)

Benim sorun olduğunu ben okumaya devam et hakkında hile yapmak için dönüş tipi değişken (olması sonucu ya da başka bir fonksiyon), ama benim geri dönüş tipi sabit (Bool).

CEVAP
2 Aralık 2011, Cuma


Hile hangi işlevleri ve dönüş türünün bir örneği için bir örnek tanımlayacaktır tür bir sınıf yapmak. Bool aslında bir sorun değil.

Variadic bir argüman alır ve Bool böyle bir fonksiyon türü bir sınıf tanımlarız yani bir döndüren bir fonksiyon yazmak için çalışıyoruz.

class Stmt a where
    tautology :: a -> Bool

Sonraki, biz variadic dönüş için bir örnek tip fonksiyon tanımlayın. Bu durumda, o Bool.

-- A Bool is a tautology if it's True.
instance Stmt Bool where
    tautology = id

Kilit kısım Bool bir argüman, ve yazın bizim sınıftan bazı türü olan işlevler için sonraki örneğidir. Bu şekilde, bu örneği eğer bir işlev birden fazla bağımsız değişken alır eğer birden çok kez uygulanır.

-- A function is a tautology if it always returns a tautology.
instance Stmt b => Stmt (Bool -> b) where
    tautology f = tautology (f True) && tautology (f False)

Bu şekilde yazma ikinci örnek Bool kafa yüzünden FlexibleInstances gerektirir. 98, biz saf Haskell ile aynı yapmak için uygun kısıtlı tipi değişken yerine kullanmanız gerekir. Örneğin Bounded Enum kullanabiliriz (Bool için de örnekleri var), ya da sana uygun girişler inşa sağlayacak kendi sınıf yapabilirsiniz.

instance (Enum a, Bounded a, Stmt b) => Stmt (a -> b) where
    tautology f = all (tautology . f) [minBound .. maxBound]

Ve işimiz bitti. Bunu bir deneyelim:

> tautology $ \x y -> (not x && not y) == not (x && y)
False
> tautology $ \x y -> (not x && not y) == not (x || y)
True

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Austin Evans

    Austin Evans

    5 AĞUSTOS 2007
  • Damien Hayes

    Damien Hayes

    11 Mart 2008
  • Dylan Brenan

    Dylan Brenan

    22 Aralık 2009