Bạn đang nói toFloat
có thể trả về bất kỳ loại nào thuộc về Floating
typeclass nhưng bạn đang hạn chế nó thành Float
, điều đó là sai. Chức năng của bạn là đa hình trong a
vì vậy bạn không thể trả về một phiên bản Floating
, nó sẽ có thể hoạt động với tất cả các phiên bản.
Otherway bạn có thể hiểu được điều này bằng cách
toFloat :: (Read a,Floating a) => String -> a
toFloat s = read s
Trong ghci
*Main> :t toFloat "12.1"
toFloat "12.1" :: (Floating a, Read a) => a
*Main> :t (toFloat "12.1" :: Float)
(toFloat "12.1" :: Float) :: Float
*Main> :t (toFloat "12.1" :: Double)
(toFloat "12.1" :: Double) :: Double
Kể từ khi nó trả về kiểu thuộc typeclass Floating
bạn sẽ có thể chuyển nó sang bất kỳ loại (thuộc Floating
) bởi cung cấp chữ ký loại rõ ràng sau khi hàm được áp dụng. Mặt khác, hãy nhớ trường hợp của bạn khi bạn đang quay trở lại Float
bây giờ bạn không thể chỉ nói rằng tôi mong đợi Double
từ chức năng này vì điều đó không thể xảy ra mà không có chuyển đổi rõ ràng.
Một cách khác để hiểu làm thế nào khủng khiếp giả định của bạn là xem xét chức năng read
read :: Read a => String -> a
Bây giờ ở đây theo bạn, bạn chỉ có thể trở lại nói Int
cho tất cả mọi thứ vì Int
có một thể hiện cho Read
. Giờ đây, bạn có thể hiểu điều gì sẽ xảy ra nếu bạn làm điều gì đó như
read "12" + (1.2 :: Double)
Cảm ơn phản ứng nhanh. Điều này làm rõ vấn đề cho tôi một cách hoàn hảo. Bằng cách nào đó nó đã không bấm cho tôi rằng người gọi chức năng của tôi có thể yêu cầu một trường hợp cụ thể của typeclass của tôi. – nottombrown