2010-06-04 72 views
16

Tại sao tôi không thể tạo các bộ dữ liệu lớn trong Haskell? Tại sao có giới hạn kích thước tuple?Giới hạn kích thước Haskell Tuple

Prelude> (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1) 

<interactive>:1:0: 
    No instance for (Show 
         (t, 
         t1, 
         t2, 
         ... 
         t23)) 
     arising from a use of `print' at <interactive>:1:0-48 
    Possible fix: 
     add an instance declaration for 
     (Show 
     (t, 
      t1, 
      t2, 
      ... 
      t23)) 
    In a stmt of a 'do' expression: print it 
+0

Liệu việc mã của bạn nếu bạn xác định Hiện dụ cho nó? –

+12

Tất nhiên là vậy. Nhưng tại sao đọc thông báo lỗi khi bạn chỉ có thể khiếu nại về SO? – jrockway

+2

Một trong những trường hợp hiếm hoi trong đó đề xuất của GHC không phải là một ý tưởng kinh khủng, khủng khiếp. – luqui

Trả lời

21

Tuples có thể có độ dài tùy ý *, nhưng Hiển thị, cũng như Eq, Ord, Read, Bounded, v.v ... chỉ được khởi tạo tối đa 15 tuple. Từ Haskell 98 report §6.1.4:

Không có trên ràng buộc về kích thước của một tuple, nhưng một số triển khai Haskell có thể hạn chế kích thước của các bộ, và hạn chế các trường hợp liên quan đến các bộ lớn hơn. Tuy nhiên, mỗi lần triển khai Haskell phải hỗ trợ tuples có kích thước tối đa 15, cùng với các trường hợp cho Eq, Ord, Bounded, Read và Show. Các Prelude và thư viện xác định chức năng tuple như zip cho các bộ lên đến một kích thước của 7.

Như những người khác đã nói, nếu bạn cần một 24-tuple, bạn nên sử dụng một cấu trúc dữ liệu tốt hơn.


Chỉnh sửa: * như của GHC 6.12.2, kích thước tối đa của một tuple là 62:

Prelude> :t (1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8) 

<interactive>:1:0: 
    A 64-tuple is too large for GHC 
     (max size is 62) 
     Workaround: use nested tuples or define a data type 
+0

Tôi tin rằng GHC giới hạn các bộ phận tới 60 thành phần, nhưng tiêu chuẩn ngôn ngữ thì không. Dù bằng cách nào, nó chỉ là ngớ ngẩn để có một tuple lớn :) – copumpkin

+0

@pumpkin: Ah phải. Đã cập nhật. – kennytm

10

Bạn có thể tạo các bộ dữ liệu lớn hơn, nhưng bạn sẽ cần tự định nghĩa chúng. Thứ hai, bạn không có một thể hiện Show, vì vậy bạn cũng sẽ cần phải viết một thể hiện cho điều đó.

Nói chung, bạn nên sử dụng các bộ dữ liệu lớn, khi bạn nên sử dụng loại dữ liệu thông minh hơn, chẳng hạn như vectơ. Chúng tôi không khuyến khích sử dụng bằng cách giới hạn kích thước được cung cấp theo mặc định.

22

Rất nhiều than phiền giữa những người bán rong, bộ đồ không phải là thành phần. Vì vậy, bất kỳ typeclass phải được xác định trên mỗi kích thước của tuple. Tôi nghĩ rằng báo cáo nói rằng các trường hợp chỉ cần được xác định lên đến 10 ngôi sao hoặc một cái gì đó như thế.

Tôi không bao giờ sử dụng nhiều hơn gấp ba lần trong thực tế. Nếu bạn đang sử dụng bộ dữ liệu để thực hiện một số loại logic cấp loại, hãy tạo một biến thể tổng hợp và sử dụng biến đó. Ví dụ:

infixr 9 :* 
data a :* b = a :* !b 

Sau đó, loại một 5ple của Ints sẽ là:

Int :* Int :* Int :* Int :* Int :*() 

Đơn vị () ở cuối là quan trọng cho loại mức logic cũng như tính nghiêm minh tính đúng đắn (bạn wouldn' t muốn yếu tố cuối cùng phải nghiêm ngặt và tất cả những yếu tố khác là lười biếng).

Lưu ý bang trong tuyên bố. Nó có nghĩa là phía bên phải của một tuple là nghiêm ngặt, để một loại như 5ple trên có thể được san phẳng xuống thành một đoạn duy nhất của bộ nhớ, để các yếu tố sau này không phải là đắt hơn để truy cập hơn những người trước đó.

+0

'(: *)' của bạn sẽ là tuyệt vời để thực hiện một quasiquoter của tôi. Các quoter cần phải có tùy chọn lớn tuples (người dùng phụ thuộc) để mang thông tin trả về từ xem mẫu trả về các loại khác nhau. Tốt hơn nhiều so với bộ làm tổ. –

+0

Nhưng (a: * b): * c không giống như: * (b: * c) phải không? Vì vậy, ngoài ký hiệu và độ chặt chẽ, nó giống như các bộ dữ liệu lồng nhau? – saolof

Các vấn đề liên quan