2013-09-21 57 views
22

Tôi không thể lấy dòng mã này được biên dịch trong Haskell nhưng nó hoạt động trên hệ thống của giáo sư của tôi. Tôi sử dụng phiên bản 7.6.2 ghci.Dòng mã Haskell không biên dịch: "Ngữ cảnh kiểu dữ liệu bất hợp pháp"

data Eq a => Shape a = Shape a 

Chính xác hơn, đây là lỗi Tôi nhận

[1 of 1] Compiling Main    (test.hs, interpreted) 

test.hs:1:6: 
Illegal datatype context (use -XDatatypeContexts): Eq a => 
Failed, modules loaded: none. 

sai lầm ở đây là gì?

Cảm ơn

+0

Bản sao có thể có của [Cách sửa lỗi "Ngữ cảnh kiểu dữ liệu bất hợp pháp" (sử dụng -XDatatypeContexts)?] (Http://stackoverflow.com/questions/22622399/how-to-fix-illegal-datatype-context-use-xdatatypecontexts) – wizzup

Trả lời

31

Giáo sư của bạn có thể đang sử dụng phiên bản GHC cũ hơn. Dòng bạn đã đăng sử dụng một tính năng gần đây đã bị xóa. Các giải pháp có thể là:

  1. Xóa Eq a => và viết data Shape a = Shape a.

  2. Như GHC cho biết, hãy cung cấp cờ -XDatatypeContexts để bật lại tính năng đã loại bỏ.

Cụ thể hơn: Eq a => phần khai báo kiểu của bạn được gọi là một bối cảnh datatype. Chức năng duy nhất của nó là hạn chế kiểu của hàm tạo Shape, do đó thay vì Shape :: a -> Shape a bạn nhận được Shape :: Eq a => a -> Shape a. Nó không giúp bạn tiết kiệm từ việc phải viết Eq a trong các chữ ký loại liên quan đến Shape s, và thực sự thậm chí sẽ yêu cầu bạn viết chúng khi bạn không cần thiết. Nó đã từng hữu ích khi các trường nghiêm ngặt trong các kiểu dữ liệu yêu cầu một ràng buộc lớp, nhưng tính năng đó đã bị loại bỏ từ lâu.

Tóm lại, việc xóa ngữ cảnh hầu như luôn là cải tiến đối với chương trình của bạn, vì vậy chúng đã bị xóa khỏi tiêu chuẩn ngôn ngữ Haskell 2011. Vì GHC 7.0.1 đã có một tùy chọn để tắt chúng và kể từ 7.2.1 nó đã được mặc định.

+0

Chắc chắn mục đích của một hạn chế như vậy không phải là để cứu tôi phải viết một cái gì đó nhưng để cải thiện an toàn loại chính xác bằng cách buộc tôi phải viết nhiều hơn tôi sẽ cần phải làm gì? – Psachnodaimonia

+0

Xin lỗi, nhập an toàn không thực sự là từ tôi đang tìm kiếm. Tôi nghĩ rằng việc thêm ngữ cảnh tạo ra một liên kết chặt chẽ hơn giữa các khả năng cú pháp của chương trình và ý định ngữ nghĩa của tôi, và trong quá trình kiểm tra kiểu sẽ làm cho một số lỗi ngữ nghĩa nhất định không thể xảy ra. – Psachnodaimonia

+0

@Psachnodaimonia: đó không phải là một quan điểm không hợp lý, nhưng tôi nghĩ tính năng đặc biệt này khó hiểu hơn là hữu ích, vì nhiều người mong đợi nó hoạt động khác với cách thực hiện. –

5

Tôi nghĩ rằng thông báo lỗi rõ ràng trong nội dung thông báo. Bạn cần một phần mở rộng cho điều đó.

{-# LANGUAGE DatatypeContexts #-} 
data Eq a => Foo a = Foo a 

Mặc dù phần mở rộng này sử dụng để được bật theo mặc định nhưng bắt đầu từ GHC 7.6, sử dụng của nó được coi deprecated và sẽ được loại bỏ trong tương lai. Vì vậy, giáo sư của bạn có thể đang sử dụng phiên bản cũ hơn của ghc.

+0

Thay vì thêm dòng đó mọi lúc (tôi cũng không biết chính xác nó là gì), tôi quyết định sử dụng 'dữ liệu Foo a = Foo a phát sinh Eq' Cảm ơn câu trả lời của bạn :) – Goutham

+1

Nó hạn chế các loại' Foo' có thể mất, để có ví dụ Eq. Giả sử 'Bar' là một kiểu không có bất kỳ cá thể' Eq' nào, bạn không thể có kiểu 'Foo Bar'. Mặt khác, việc phát sinh 'Eq' sẽ lấy ra một cá thể' Eq' mặc định cho 'Foo'. Bạn có thể có một loại 'Foo Bar' (trong đó' Bar' không có 'Eq' instance) nhưng bạn không thể sử dụng' == 'trên nó. – Satvik

3

Xem thêm https://stackoverflow.com/a/22622591/2008899 giải thích "Tại sao?" đằng sau sự thay đổi ngôn ngữ cũng như hiển thị một ví dụ GADT làm những bối cảnh datatype nào là được cho là để cung cấp.