phép nói rằng tôi đã có đoạn mã sauHaskell: Loại an toàn với các giá trị Boolean logic khác nhau
type IsTall = Bool
type IsAlive = Bool
is_short_alive_person is_tall is_alive = (not is_tall) && is_alive
Này, sau này, tôi đã có những điều sau
a :: IsAlive
a = False
b :: IsTall
b = True
Và gọi sau , nhận được hai đối số xung quanh một cách sai lầm:
is_short_alive_person a b
này biên dịch thành công không may, và khi chạy người cao chết thay vào đó được tìm thấy thay vì những người sống ngắn.
Tôi muốn ví dụ trên không được biên dịch.
nỗ lực đầu tiên của tôi là:
newtype IsAlive = IsAlive Bool
newtype IsTall = IsTall Bool
Nhưng sau đó tôi không thể làm điều gì đó như thế nào.
switch_height :: IsTall -> IsTall
switch_height h = not h
Như not
không được định nghĩa trên IsTall
s, chỉ Bool
s.
Tôi có thể trích xuất rõ ràng Bool
mọi lúc, nhưng điều đó phần lớn đánh bại mục đích.
Về cơ bản, tôi muốn IsTall
s tương tác với IsTall
s khác, giống như họ đang Bool
s, ngoại trừ họ sẽ không tương tác với Bool
s và IsAlive
s mà không có một diễn viên rõ ràng.
Cách tốt nhất để đạt được điều này là gì.
p.s. Tôi nghĩ rằng tôi đã đạt được điều này với những con số bằng cách thực hiện trong GHC:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype UserID = UserID Int deriving (Eq, Ord, Num)
newtype GroupID = GroupID Int deriving (Eq, Ord, Num)
(tức là của UserID và GROUPID không nên tương tác)
nhưng tôi dường như không thể làm điều này với Bool
s (bắt nguồn Bool không hoạt động). Tôi thậm chí không chắc chắn ở trên là cách tiếp cận tốt nhất anyway.
Các loại 'IsTall' và' IsAlive' mong muốn của bạn là một ý tưởng tồi tệ. Đó là một khái quát sai lầm của ý tưởng thường phong nha của việc sử dụng các loại rời rạc để đảm bảo an toàn loại. So sánh điều này với 'UserID' và' GroupID' của bạn; trong trường hợp đó, có ý nghĩa để có các kiểu riêng biệt bởi vì nó không có ý nghĩa khi chuyển một 'UserId' trong đó một' GroupID' là cần thiết, hoặc thêm vào một nhóm khác (mặc dù có lẽ không nên thực hiện 'Num'). Tuy nhiên, nó có ý nghĩa để kiểm tra xem một người là cao * và * sống, cao * hoặc * còn sống, * không * cao * và * còn sống, v.v. –
sacundim: Ở mức độ lớn, tôi đã thay đổi ý định của mình đến thời điểm này lượt xem. Tôi đã sử dụng những thứ như 'newtype Height = Tall | Short' và sau đó thực hiện 'x == Tall', v.v. Một chút gõ, nhưng tôi nghĩ nó làm cho mã dễ đọc hơn và an toàn hơn. – Clinton