2009-12-28 28 views
8

Tôi đang học Haskell. Tôi đã tạo ra chức năng trả về bảng nhân lên đến 'n' trong cơ sở 'b'. Các số được đệm thành chữ số 'w'. Bước cuối cùng, tôi muốn tự động tính toán 'w'. Tại sao điều này không biên dịch?Không có trường hợp nào cho (Floating Int)

-- 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)) 

lỗi:

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)) 

Trả lời

10

logBase mất hai thông số đó thực hiện typeclass nổi. Bạn sẽ cần phải gọi từIntegral trên các tham số trước khi chuyển chúng đến logBase. Đây được biên soạn cho tôi với 6.10.3:

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

Bạn phải nhớ rằng Haskell là rất mạnh mẽ gõ, vì vậy bạn có thể không chỉ là giả định rằng các tham số Int cung cấp cho chức năng của bạn sẽ tự động bị cưỡng chế những con số nổi chức năng đăng nhập thường mất.

5

logBase được khai báo để hoạt động trên các loại điểm động. Int không phải là loại dấu phẩy động và có no automatic conversion in Haskell. Hãy thử điều này:

-- 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

Tôi đoán bạn cũng sẽ cần '(cơ sở từ gốc) '. –

+0

@ Jason: Không phải với loại Dan đã cho chức năng đó, bạn sẽ không. – Chuck

+0

Vâng, phụ thuộc vào cách bạn muốn sử dụng nó. Hoặc làm điều đó như tôi có nó nếu nó OK để thay đổi chữ ký loại, hoặc sử dụng phiên bản của Andy nếu không. –

3

Từ Prelude:

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

Nó có nghĩa là sử dụng logBase bạn phải sử dụng một loại nổi. Nhưng Int không phải là một loại nổi, và không có chuyển đổi tự động với nhiều loại số, vì vậy bạn phải chuyển đổi nó từ Int để một kiểu Floating:

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

chức năng toEnum lấy một int như tham số và trả về một " Enum "loại. Phần tốt là nổi đó là một thể hiện của Enum, vì vậy bạn có thể sử dụng nó

toEnum :: Enum a => Int -> a 

Bạn nên đọc/tài liệu bạn về các lớp học kiểu tiêu chuẩn trong Haskell với nhiều loại số (Num, Fractional, Integral, nổi ...) vì chúng thường xuất hiện trong mã, việc chuyển đổi học tập có thể hữu ích.

Chỉnh sửa: điều này Haskell Wiki Book cung cấp đồ họa rất hữu ích về mối quan hệ giữa lớp loại tiêu chuẩn, bao gồm các loại số.

Các vấn đề liên quan