2012-06-24 14 views
7

Proje Euler'da 20 sorun yaşıyorum - 100'lük rakamların toplamını bulmak! (factorial, coşku değil).Etkileşimli ve derlenmiş Haskell arasında farklı sonuçlar (Project Euler 20)

import Data.Char 

main = print $ sumOfDigits (product [1..100]) 

sumOfDigits :: Int -> Int 
sumOfDigits n = sum $ map digitToInt (show n) 

Ben ghc -o p20 p20.hs ile derlenmiş ve benim komut satırında sadece 0 alma, bunu infaz:

İşte yazdığım bir programdır.

Şaşkın, ben ghci çağrılan ve aşağıdaki satırı ran:

sum $ map Data.Char.digitToInt (show (product [1..100]))

Bu doğru cevap döndü. Derlenmiş sürüm neden çalışmadı?

cevap

15

neden türünü imza

sumOfDigits :: Int -> Int 
sumOfDigits n = sum $ map digitToInt (show n) 

kullanım

sumOfDigits :: Integer -> Int 

olduğunu ve (istediğini) GHCi aynı şeyi alacak.

Int, "ints" boyutundaki makine kelimesi türündeyken, Integer, matematiksel olarak doğru, keyfi duyarlıklı Integers türüdür.

Eğer GHCi içine

:t product [1..100] 

yazarsanız Enum ve Num tipi sınıflarının örneklerini vardır HERHANGİ türü için olduğu

product [1..100] :: (Enum a, Num a) => a 

gibi bir şey, product [1..100] bir değer olabilir alacak bu tür

product [1..100] :: Integer 

93326215443944152681699238856266700490715 dönmelidir Makinenizden çok daha büyük olan 96826438162146859296389521759999322991560894146397615651828625369792082722375825118521091686400000000000000000000000000, makinenizde bir kelime olarak temsil edebilecek gibi olabilir. rulo

product [1..100] :: Int 

üzerinde

0 bu verilen dönecektir çünkü Muhtemelen, bunu birden olası uyumsuz yorumlara çünkü

sum $ map Data.Char.digitToInt (show (product [1..100])) 

, kontrol yazın olmaz düşünebilir. Ancak, bir hesap makinesi olarak kullanılabilmesi için Haskell, bu gibi durumlarda Integer'u kullanmaya karar verir ve böylece davranışınızı açıklar. Aynı nedenle

, en genel tip

sumOfDigits :: Show a => a -> Int 
olduğundan size, sumOfDigits o istediğini yapardı açık tip imzası verilen DEĞİL olsaydı
İlgili konular