Ràng buộc như vậy sẽ gây ra lỗi loại nếu nó xuất hiện dưới dạng ràng buộc nhất định. Nói chung, điều này áp dụng cho bất kỳ ràng buộc nào mà người đánh máy xem xét là không thể.
Thậm chí viết một hàm
f :: ('True ~ 'False) => x
f = undefined
không typecheck, vì bối cảnh của một hàm là một hạn chế nhất định trong cơ thể của hàm - và 'True ~ 'False
đơn giản là không thể xuất hiện như là một hạn chế nhất định.
Tốt nhất bạn có thể có, ví dụ:
import Data.Type.Equality ((:~:)(..))
type family (==) (a :: k) (b :: k) :: Bool where
a == a = 'True
a == b = 'False
f :: ((x == y) ~ 'False) => x :~: y -> a
-- f Refl = undefined -- Inaccessible code
f = \case{}
mà lại quay trở lại EmptyCase
, lần này trên :~:
. Lưu ý rằng
f :: ((x == y) ~ 'False, x ~ y) => a
cũng làm giảm tới một hạn chế trivially không thể, bởi vì x == x
giảm tới True
. Bạn có thể viết một vị bình đẳng mà không làm giảm cho trivially loại bằng nhau (ví dụ như một trong Data.Type.Equality
), cho phép bạn viết:
import Data.Type.Equality
f :: ((x == y) ~ 'False, x ~ y) => Proxy '(x,y) -> a
f = undefined
Có thể có một cách để viết chức năng này mà không cần undefined
nhưng nó là loại tranh luận dù sao kể từ khi loại hình này ngay lập tức được giảm GHC:
>:t f
f :: forall (k :: BOX) (y :: k) a. ((y == y) ~ 'False) => Proxy '(y, y) -> a
Thậm chí nếu không có sự hạn chế đó, nó là definitionally không thể gọi hàm Proxy '(y,y) -> a
với hai khác nhau loại. Không có cách nào để ẩn một ràng buộc bình đẳng ~
từ máy đánh chữ - bạn phải sử dụng một hình thức bình đẳng khác, cái không giảm xuống ~
.
Tôi không có chuyên gia, nhưng tôi đoán rằng ngay sau khi một ràng buộc liên quan đến không có biến, GHC cố gắng để tạo ra một từ điển/bằng chứng cho nó. Nếu không thành công, một lỗi kiểu được tạo ra. Sẽ rất thú vị khi xem điều gì sẽ xảy ra nếu ví dụ: ''c' && True :: Bool ~ Char => Bool', cho phép ràng buộc nổi xung quanh. Có lẽ phương pháp thất bại sớm hiệu quả hơn hoặc tạo ra các lỗi tốt hơn (?) – chi
Bạn có thể 'EmptyCase' trên [' Dict'] (https://hackage.haskell.org/package/constraints-0.6/docs/Data- Constraint.html # g: 2). –