2011-07-10 28 views
7

Xin chào Haskellers và Haskellettes,Haskell - lồng danh sách rỗng

khi đọc http://learnyouahaskell.com/ một người bạn của tôi đã đưa ra một vấn đề:

Có thể trong Haskell để viết một hàm đệ quy cung cấp cho True nếu tất cả các tiểu -sub -_- sublists rỗng. Đoán đầu tiên của tôi là - nên - nhưng tôi có một vấn đề lớn chỉ cần viết chú thích kiểu.

ông đã cố gắng một cái gì đó giống như

nullRec l = if null l 
       then True 
       else if [] `elem` l 
        then nullRec (head [l]) && nullRec (tail l) 
        else False 

đó là - không hoạt động - :-)

tôi đã đưa ra một cái gì đó giống như

  • gấp với concat - để có được aa danh sách dài đơn
    (khiến tôi gặp sự cố khi triển khai)
  • hoặc tạo một kiểu dữ liệu treelike vô hạn - và thực hiện việc này từ danh sách
    (chưa triển khai)

nhưng âm thanh sau này hơi giống như quá mức cho vấn đề này. ý tưởng của bạn là gì - trên một chủ nhật đầy nắng như thế này ;-)

Cảm ơn trước


như một phản ứng đối với tất cả các ý kiến ​​- phong cách xấu là này tôi muốn thêm này chỉ cần thử nghiệm!
KHÔNG thử ở nhà! ;-)

+3

Hãy nghĩ về loại chức năng như vậy (nếu bạn thực hiện nó trên danh sách bình thường)! – yatima2975

+0

tôi đã nghĩ về nó - nó phải là loại vô hạn [[… [a]…]] nhưng điều đó không thể viết ra trong haskell - đó là lý do tại sao tôi nghĩ ra cách tiếp cận thứ hai. Nhưng có cách nào dễ hơn để làm điều này không. Ngoài ra bộ não của tôi hơi chậm một chút khi tôi bị bệnh ngày hôm nay. – epsilonhalbe

+2

Bệnh hay không, bạn đang đi đúng hướng! Thật dễ dàng để viết một họ các hàm 'nullRec2 :: [[a]] -> Bool',' nullRec3 :: [[[a]]] -> Bool' và vân vân (thử một cặp!), Nhưng bạn không thể khiến chúng phù hợp với một chữ ký kiểu đơn dễ dàng. Bạn cần loại cây như dữ liệu Tree a = Branch [Tree a] | Node a' hoặc có thể có một cái gì đó có thể với typeclasses (chưa nghĩ nhiều về cách tiếp cận này). – yatima2975

Trả lời

5

Làm thế nào về một typeclass?

{-# LANGUAGE FlexibleInstances, OverlappingInstances #-} 

class NullRec a where 
    nullRec :: a -> Bool 

instance NullRec a => NullRec [a] where 
    nullRec [] = True 
    nullRec ls = all nullRec ls 

instance NullRec a where 
    nullRec _ = False 

main = print . nullRec $ ([[[[()]]]] :: [[[[()]]]]) 
+5

Chính xác hơn, bạn đang sử dụng không chỉ một loại lớp mà còn là phần mở rộng GHC [OverlappingInstances] (http://www.haskell.org/ghc/docs/7.0.4/html/users_guide/type-class-extensions.html # instance-overlap). Nếu không có phần mở rộng này, ngay cả khi sử dụng một loại lớp không thể đạt được những gì được yêu cầu trong câu hỏi. Điều này gợi ý rằng nếu bất cứ ai _has to_ thực hiện điều này (không phải là thử nghiệm), chương trình có thể không được thiết kế đúng cách. –

4

Điều này không thể sử dụng đa hình tham số, vì những điều sau đây.

Xem xét các giá trị:

x = [8] :: [Int] 
y = [3.0] :: [Double] 
z = [[]] :: [[Int]] 

Rõ ràng, bạn muốn chức năng của bạn để làm việc với cả hai xy, do đó loại của nó phải null1 :: [a] -> Bool. (Ai đó có thể giúp tôi làm cho lập luận này trông hình thức? Làm thế nào tôi có thể thấy rằng đây là độc đáo cụ thể nhất bối cảnh ít loại unifiable với [Int] -> Bool[Double] -> Bool? Có tên cho mối quan hệ đó giữa các loại?)

Bây giờ , nếu bạn có loại này, thì null1 z sẽ bằng null1 x bởi vì chúng chỉ khác nhau về giá trị của các phần tử danh sách, được trừu tượng hóa. (thậm chí không gần bằng chứng chính thức một lần nữa :()

gì bạn muốn cho znull2 :: [[a]] -> Bool, mà sẽ khác nhau trong hành vi, và do đó đem lại null1null2 cùng tên sẽ đòi hỏi quá tải.(xem câu trả lời của FUZxxl)

+0

Tôi thấy lập luận đó khá thuyết phục. – luqui

+0

Tôi cảm thấy giống như 'null1. (: []) :: a -> Bool' đưa chúng ta đến gần hơn với bằng chứng chính thức, nhưng tôi vẫn không biết làm thế nào để thực hiện bước cuối cùng (cho thấy rằng 'a -> Bool' giống như' Bool'). – Rotsor

+0

Đó là loại định lý tự do ngược lại, nhưng giới hạn dưới lớn nhất của 'Int' và' Double' (trên mạng của các kiểu không có ngữ cảnh Haskell, với sự thay thế là mối quan hệ) là 'a', vì bạn không thể các biến kiểu thay thế trong cả hai (không có bất kỳ) và kết thúc với cùng một loại. Hoặc tôi có nhận được hướng lên & xuống của tôi trộn lẫn không? – yatima2975