Tôi muốn viết một phiên bản an toàn toEnum
:an toàn và đa hình toEnum
safeToEnum :: (Enum t, Bounded t) => Int -> Maybe t
Một thực hiện ngây thơ:
safeToEnum :: (Enum t, Bounded t) => Int -> Maybe t
safeToEnum i =
if (i >= fromEnum (minBound :: t)) && (i <= fromEnum (maxBound :: t))
then Just . toEnum $ i
else Nothing
main = do
print $ (safeToEnum 1 :: Maybe Bool)
print $ (safeToEnum 2 :: Maybe Bool)
Và nó không hoạt động:
safeToEnum.hs:3:21:
Could not deduce (Bounded t1) from the context()
arising from a use of `minBound' at safeToEnum.hs:3:21-28
Possible fix:
add (Bounded t1) to the context of an expression type signature
In the first argument of `fromEnum', namely `(minBound :: t)'
In the second argument of `(>=)', namely `fromEnum (minBound :: t)'
In the first argument of `(&&)', namely
`(i >= fromEnum (minBound :: t))'
safeToEnum.hs:3:56:
Could not deduce (Bounded t1) from the context()
arising from a use of `maxBound' at safeToEnum.hs:3:56-63
Possible fix:
add (Bounded t1) to the context of an expression type signature
In the first argument of `fromEnum', namely `(maxBound :: t)'
In the second argument of `(<=)', namely `fromEnum (maxBound :: t)'
In the second argument of `(&&)', namely
`(i <= fromEnum (maxBound :: t))'
Cũng như tôi hiểu được thông báo, trình biên dịch không nhận ra rằng minBound
và maxBound
nên sản xuất chính xác cùng loại như trong loại kết quả của safeToEnum
kiểm tra khai báo loại rõ ràng (:: t
). Bất kỳ ý tưởng làm thế nào để sửa chữa nó?
Giải Quyết
Cả hai của camccann và giải pháp làm việc của Dave (mặc dù một Dave cần phải được điều chỉnh). Cảm ơn cả hai (nhưng tôi chỉ có thể chấp nhận một). Ví dụ làm việc với ScopedTypeVariables:
{-# LANGUAGE ScopedTypeVariables #-}
safeToEnum :: forall t . (Enum t, Bounded t) => Int -> Maybe t
safeToEnum i =
if (i >= fromEnum (minBound :: t)) && (i <= fromEnum (maxBound :: t))
then Just . toEnum $ i
else Nothing
Có. Điều này cũng hoạt động. Ý kiến hay. – sastanin
Tôi thích các giải pháp của bạn. Thật tuyệt khi 'r' không thực sự được đánh giá trong' asTypeOf' (phiên bản thứ hai). – sastanin
@jetxee: Vâng, nó chắc chắn được đánh giá nếu bạn thực sự * sử dụng * nó ... mà tất nhiên sẽ không xảy ra nếu kết quả là 'Không có gì'. Không phải là tuyệt vời để được lười biếng? –