SORU
19 EKİM 2011, ÇARŞAMBA


Nasıl Haskell, basit bir beşgen kullanmaktır çalışır?

Haskell tür güvenliğini ikinciyokiçin bağımlı yazılan dil. Ama tabii yazmak-bitkin görünüyor ki bazı derin büyü Text.Printf ile devam ediyor.

> printf "%d\n" 3
3
> printf "%s %f %d" "foo" 3.3 3
foo 3.3 3

Bunun arkasında derin büyü nedir? Nasıl Text.Printf.printf işlevi bu gibi variadic argümanlar alabilir?

Genel techinque variadic değişkenler için izin vermek için Haskell kullanılır, nedir ve nasıl çalışır?

(Yan not: bazı tip güvenlik görünüşe göre bu tekniği kullanırken kaybolur.)

> :t printf "%d\n" "foo"
printf "%d\n" "foo" :: (PrintfType ([Char] -> t)) => t

CEVAP
19 EKİM 2011, ÇARŞAMBA


Hile türü sınıfları kullanmaktır. printf, Bu durumda anahtarı PrintfType yazın sınıftır. Herhangi bir yöntem göstermiyor, fakat önemli parçası türleri zaten.

class PrintfType r
printf :: PrintfType r => String -> r

printf aşırı bir dönüş türü vardır. Önemsiz durumda, IO () r adresi olmak istiyoruz bu yüzden ekstra bir argüman var. Bunun için örnek var

instance PrintfType (IO ())

Bağımsız değişken bir dizi desteklemek için gelecek,, örnek düzeyinde özyineleme kullanmak için ihtiyacımız var. Özellikle eğer r ** 20, fonksiyon türü ise x -> r PrintfType böylece örneğine ihtiyacımız var.

-- instance PrintfType r => PrintfType (x -> r)

Tabii ki, biz sadece aslında biçimlendirilebilir iddialarını desteklemek için. Bu sınıfı PrintfArg burada devreye giriyor. Gerçek bir kopyası

instance (PrintfArg x, PrintfType r) => PrintfType (x -> r)

İşte Show sınıf içinde bağımsız değişken herhangi bir sayı alır ve onları yazdıran basit bir versiyonu:

{-# LANGUAGE FlexibleInstances #-}

foo :: FooType a => a
foo = bar (return ())

class FooType a where
    bar :: IO () -> a

instance FooType (IO ()) where
    bar = id

instance (Show x, FooType r) => FooType (x -> r) where
    bar s x = bar (s >> print x)

Burada, bar bu noktada biz sadece çalıştırmak daha fazla bağımsız değişken vardır hayır kadar inşa edilmiş olan IO bir eylem yinelemeli olarak alır.

*Main> foo 3 :: IO ()
3
*Main> foo 3 "hello" :: IO ()
3
"hello"
*Main> foo 3 "hello" True :: IO ()
3
"hello"
True

QuickCheck da Testable sınıf temel durum için bir örnek olduğu aynı tekniği kullanır, Bool Arbitrary sınıf değişkenleri hangi işlevler için bir özyinelemeli bir.

class Testable a
instance Testable Bool
instance (Arbitrary x, Testable r) => Testable (x -> r) 

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • bmarian22

    bmarian22

    22 Aralık 2007
  • MagmaRhino

    MagmaRhino

    16 Temmuz 2011
  • Rayone GB

    Rayone GB

    14 Temmuz 2007