2009-12-28 16 views
8

Haskell'i öğreniyorum. 'B' tabanda 'n' çarpma tablosunu döndüren fonksiyon yarattım. Rakamlar "w" basamaklarına doldurulur. Son adım olarak, ben 'w' otomatik olarak hesaplamak istiyorum. Neden bu derleme değil?(Floating Int) için bir örnek yok

-- Number of digits needed for the multiplication table n*n in base 'base' 
nOfDg :: Int -> Int-> Int 
nOfDg n base = 1 + floor (logBase base (n*n)) 

hatası:

No instance for (Floating Int) 
    arising from a use of `logBase' at C:\haskel\dgnum.hs:4:24-38 
    Possible fix: add an instance declaration for (Floating Int) 
    In the first argument of `floor', namely `(logBase b (n * n))' 
    In the second argument of `(+)', namely `floor (logBase b (n * n))' 
    In the expression: 1 + floor (logBase b (n * n)) 

cevap

10

logBase yüzen typeclass uygulamak iki parametre alır. Parametrelere logBase'e iletmeden önce, parametrelerden çağırmanız gerekir.

nOfDg :: Int -> Int-> Int 
nOfDg n base = 1 + floor (logBase (fromIntegral base) (fromIntegral (n*n))) 

Sen Haskell çok güçlü yazıldığını hatırlamak zorunda, bu yüzden sadece işlevine verilen Int parametreleri otomatik kayan sayılara zorla olacağını kabul edemeyiz: Bu 6.10.3 ile benim için derlenmiş Bu günlük fonksiyonları genellikle alır. Kayan nokta türleri üzerinde çalıştığı bildirilen

5

logBase bildirilmiştir. Int, bir kayan nokta türü değil ve no automatic conversion in Haskell var. Bu deneyin:

-- Number of digits needed for the multiplication table n*n in base 'base' 
nOfDg :: Int -> Float -> Int 
nOfDg n base = 1 + floor (logBase base (fromIntegral (n*n))) 
+0

Sanırım ayrıca '(FromIntegral base') 'e ihtiyacınız olacak. –

+0

@ Jason: Dan'in bu işlevi yerine getirmediği gibi, yapmayacaksın. – Chuck

+0

Evet, nasıl kullanmak istediğinize bağlı. Ya tür imzayı değiştirmek için sorun yoksa ya da olmasa da Andy versiyonunu kullanıyorum gibi var. –

3

Prelude Gönderen:

logBase :: Floating a => a -> a -> a 

O logBase kullanarak yüzen türünü kullanarak gerektiği anlamına gelir. Ama Int yüzen Tip değildir ve bir Kayan türüne Int onu dönüştürmek zorunda sayısal türleri için otomatik bir dönüşüm vardır: toEnum fonksiyonu parametre olarak int alıp dönmek

nOfDg n base = 1 + floor (logBase (toEnum base) (toEnum n)) 

bir " Enum "türü. iyi kısmı bu Float Enum bir örneğidir, yani Yüzer, sayısal türleri (Num, Kesikli için Haskell standart tip sınıfları hakkında belgelemek o

toEnum :: Enum a => Int -> a 

Sen/okumalısınız İntegral kullanabilirsiniz ...) genellikle kod içinde açılırken, dönüşümleri öğrenmek yararlı olabilir.

Düzenleme: bu, Haskell Wiki Book sayısal türler de dahil olmak üzere standart tür sınıfı arasında çok yararlı bir ilişki grafiği sağlar.