2012-08-23 15 views
10

Tôi đang viết một hàm để đơn giản hóa biểu thức Boolean. Ví dụ: Nand(A, A) == Not(A). Tôi đã cố gắng thực hiện quy tắc đặc biệt này sử dụng kết hợp mô hình, như vậy:Ngụ ý bình đẳng trong kết hợp mẫu Haskell

-- Operands equivalent - simplify! 
simplify (Nand q q) = Not (simplify q) 
-- Operands must be different, so recurse. 
simplify (Nand q q') = Nand (simplify q) (simplify q') 

Khi biên soạn, tôi nhận được lỗi:

Conflicting definitions for `q' 
Bound at: boolean.hs:73:21 
      boolean:73:29 
In an equation for `simplify' 

Tôi nghĩ rằng tôi hiểu những gì đang xảy ra, và tôi đã đã làm việc xung quanh nó, nhưng tôi chỉ muốn biết:

  1. Tại sao loại kết hợp mẫu này lại không thể?
  2. Có cách giải quyết thành ngữ không?

Tiết lộ đầy đủ: điều này liên quan đến bài tập ở nhà, nhưng mục đích của khóa học không phải là để tìm hiểu Haskell và tôi đã tự giải quyết theo cách riêng của mình.

+11

Điệp khúc ấy sử dụng một biến hai lần được gọi là một tổ chức phi mô hình tuyến tính. Có những ngôn ngữ cung cấp các mẫu phi tuyến tính như Erlang và tôi nghĩ đó là một lựa chọn thiết kế để không bao gồm chúng trong Haskell. Bài đăng danh sách gửi thư http://www.mail-archive.com/[email protected]/msg03721.html chứa một số đối số chống lại các mẫu phi tuyến tính nhưng chúng là các đối số cấp cao. –

+1

Lưu ý rằng (Nand q q ') không ngụ ý rằng q và q' khác nhau. q = 3 q '= 3 (Tôi nghĩ đây là lý do cho việc thiết kế) –

+1

@Vixen, tốt, nếu mẫu đầu tiên không khớp, nó có nghĩa là chúng khác nhau trong mẫu thứ hai ... – dflemstr

Trả lời

2

Bạn có thể dính vào phong cách ban đầu của bạn:

-- Operands equivalent - simplify! 
simplify (Nand q q') | q == q' = Not (simplify q) 
-- Operands must be different, so recurse. 
simplify (Nand q q') = Nand (simplify q) (simplify q') 

Ngoài ra, tôi nghĩ rằng bạn nên đơn giản hóa trước khi thử nghiệm bình đẳng và không sau:

simplify (Nand q q') = if qs == qs' then Not qs else Nand qs qs' where 
    qs = simplify q 
    qs' = simplify q' 
+1

Bắt tốt với sự đơn giản hóa trước khi kiểm tra bình đẳng! –

14

Các giải pháp tôi đã tìm thấy là sử dụng vệ sĩ để kiểm tra sự bình đẳng của phụ cấu trúc:

simplify (Nand q q') 
    -- Operands equivalent - simplify! 
    | q == q' = Not (simplify q) 
    -- Operands different - recurse. 
    | otherwise = Nand (simplify q) (simplify q') 
+0

Đây có lẽ là cách để làm điều đó, vấn đề là bạn không thể tái sử dụng cùng một mẫu như bạn đã cố gắng làm. Tôi đã làm như vậy trước đây, và về cơ bản là cùng một giải pháp. –

1

Các "câu trả lời" là bạn không được phép đề cập đến biến hai lần trong một mẫu. Không phải trong Haskell. Cách tốt nhất để giải quyết vấn đề này là cách bạn đã khám phá ra - hãy sử dụng các mô hình bảo vệ để kiểm tra sự bình đẳng hoặc bất bình đẳng.