2013-06-28 33 views
5

Tôi vẫn còn rất nhiều cố gắng để có được vào haskell, nhưng tôi đã nhận thấy một cái gì đó mà làm phiền tôi khá một chút.Tại sao không hiển thị được coi là một chuyển đổi trong haskell?

Trong sách "Learn You a Haskell for Great Good!" có phần này cho thấy việc sử dụng các nhân viên bảo vệ trong khớp mẫu, trong trường hợp cuốn sách là một hàm nhỏ tính toán bmi của một người, nó có một chút giống như thế này nhẹ để không vi phạm bản quyền hoặc bất kỳ):

bmiCalc :: (RealFloat a) => a -> a -> String 
bmiCalc weight height 
    | bmi <= 18.5 = "skinny" 
    | bmi <= 25.0 = "normal" 
    | bmi <= 30.0 = "fat" 
    | otherwise = "obese" 
    where bmi = weight/height^2 

đó là tất cả tiền phạt và dandy mã hoạt động như quảng cáo, nhưng tôi nghĩ, nếu nó cũng cho thấy những gì bmi nó tính là cùng với các văn bản không?

Vì vậy, tôi đã viết lại đoạn code như thế này:

bmiCalc :: (RealFloat a) => a -> a -> String 
bmiCalc weight height 
    | bmi <= 18.5 = "skinny, " ++ show bmi 
    | bmi <= 25.0 = "normal, " ++ show bmi 
    | bmi <= 30.0 = "fat, " ++ show bmi 
    | otherwise = "obese, " ++ show bmi 
    where bmi = weight/height^2 

Expecting "hiển thị" để làm việc như ToString làm trong java và C#
Boy là tôi sai.

ghci đã cho tôi thông báo lỗi khó chịu lớn này:

Could not deduce (Show a) arising from a use of `show' 
from the context (RealFloat a) 
    bound by the type signature for 
      bmiCalc :: RealFloat a => a -> a -> String 
    at file.hs:1:16-48 
Possible fix: 
    add (Show a) to the context of 
    the type signature for bmiCalc :: RealFloat a => a -> a -> String 
In the second argument of `(++)', namely `show bmi' 
In the expression: "skinny, " ++ show bmi 
In an equation for `bmiCalc': 
    bmiCalc weight height 
     | bmi <= 18.5 = "skinny, " ++ show bmi 
     | bmi <= 25.0 = "normal, " ++ show bmi 
     | bmi <= 30.0 = "fat, " ++ show bmi 
     | otherwise = "obese, " ++ show bmi 
     where 
      bmi = weight/height^2 
Failed, modules loaded: none. 

tại sao vậy? tại sao nó không cho phép tôi nối thêm thứ xuất hiện để trả về một chuỗi, thành một chuỗi? Ý tôi là theo như tôi đã hiểu "skinny, " ++ show bmi là một chuỗi ... đó chính xác là chữ ký loại nói tôi phải trả lại

vì vậy tôi đã làm gì sai ở đây?

+1

Bạn đã thử đề xuất từ ​​thông báo lỗi (ngay sau "Có thể khắc phục")? – Yuras

+2

Tương đương Java tương đương sẽ là 'show' là một phương thức của giao diện' Show', và giá trị của bạn 'a' không cần thiết để thực hiện giao diện đó, vì vậy có một lỗi kiểm tra kiểu biên dịch - điều tương tự đã xảy ra trong Java. –

+0

Nó từng là trường hợp mà typeclass 'RealFloat' có' Show' là một trong những điều kiện tiên quyết của nó (thông qua 'Num'), nhưng điều này đã thay đổi cách đây không lâu. LYAH đã lỗi thời về vấn đề này (xem http://learnyouahaskell.com/types-and-typeclasses#typeclasses-101, tìm kiếm 'Để tham gia Num') – yatima2975

Trả lời

9

Thay đổi kiểu chữ ký:

bmiCalc :: (RealFloat a, Show a) => a -> a -> String 

Bởi vì bạn muốn sử dụng các hàm thành viên show, từ Show typeclass; nhưng bạn chưa chỉ định rằng trong ràng buộc hàm, và ghci không có cách nào để suy ra điều đó đúng.

+0

Điều thú vị là, tôi đã cố gắng làm điều này trước và nó không hoạt động ... nó bằng cách nào đó bây giờ .. cảm ơn anyways! –

+5

Cách dễ nhất khi bạn có lỗi như vậy là xóa chữ ký kiểu, tải lại tệp trong ghci và gõ ': t bmiCalc'. Đó là cách tôi thêm tất cả chữ ký của tôi, cuối cùng. – mhitza

+0

mẹo tốt đẹp cảm ơn rất nhiều! –

2

RealFloat không phải là loại có thể hiển thị. Bạn sẽ phải thêm ràng buộc chương trình.

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