Đầu tiên là một thuật ngữ ngắn hạn: Tôi sẽ gọi cả hai "mẫu phù hợp" này. Tôi không chắc rằng có một thuật ngữ tốt để phân biệt kiểu trùng khớp theo trường hợp và mẫu phù hợp-qua-nhiều định nghĩa.
Sự khác biệt về mặt kỹ thuật giữa hai loại này thực sự khá nhẹ. Bạn có thể tự xác minh điều này bằng cách yêu cầu GHC đổ lõi mà nó tạo ra cho hai hàm, sử dụng cờ -ddump-simpl
. Tôi đã thử điều này ở một vài mức tối ưu khác nhau, và trong mọi trường hợp, sự khác biệt duy nhất trong Core là đặt tên. (Nhân tiện, nếu có ai biết chương trình "khác biệt ngữ nghĩa" tốt cho Core - mà biết về ít nhất là tương đương alpha - Tôi rất thích nghe về nó!)
Có một vài nhỏ gotchas để xem ra cho, mặc dù. Bạn có thể tự hỏi liệu những điều sau đây cũng tương đương:
{-# LANGUAGE LambdaCase #-}
lastButOne = \case
[] -> error "Empty List"
(x:[]) -> error "Only One Element"
(x:[x2]) -> x
(x:xs) -> lastButOneCase xs
Trong trường hợp này, câu trả lời là có. Nhưng xem xét việc này tương tự như nhìn một:
-- ambiguous type error
sort = \case
[] -> []
x:xs -> insert x (sort xs)
Đột nhiên đây là một CAF typeclass-đa hình, và vân vân GHCs cũ này sẽ kích hoạt những hạn chế monomorphism và gây ra lỗi, trong khi phiên bản một cách hời hợt giống hệt với một Lập luận rõ ràng không:
-- this is fine!
sort [] = []
sort (x:xs) = insert x (sort xs)
sự khác biệt nhỏ khác (mà tôi quên mất - cảm ơn bạn đã nhắc nhở tôi Thomas DuBuisson) là trong việc xử lý các khoản nơi. Vì các mệnh đề được gắn vào các trang liên kết, chúng không thể được chia sẻ trên nhiều phương trình nhưng có thể được chia sẻ qua nhiều trường hợp.Ví dụ:
-- error; the where clause attaches to the second equation, so
-- empty is not in scope in the first equation
null [] = empty
null (x:xs) = nonempty
where empty = True
nonempty = False
-- ok; the where clause attaches to the equation, so both empty
-- and nonempty are in scope for the entire case expression
null x = case x of
[] -> empty
x:xs -> nonempty
where
empty = True
nonempty = False
Bạn có thể nghĩ điều này có nghĩa bạn có thể làm điều gì đó với phương trình mà bạn không thể làm với trường hợp biểu thức, cụ thể là, có ý nghĩa khác nhau đối với cùng tên trong hai phương trình, như thế này:
null [] = answer where answer = True
null (x:xs) = answer where answer = False
Tuy nhiên, kể từ khi mô hình của case
biểu là các trang web liên kết, điều này có thể được mô phỏng trong case
biểu thức cũng như:
null x = case x of
[] -> answer where answer = True
x:xs -> answer where answer = False
Cho dù mệnh đề where
được gắn vào mẫu của case
hay phương trình phụ thuộc vào thụt đầu dòng, tất nhiên.
Tôi thích cái ngắn hơn hai dòng. – Bergi
Các biểu thức trường hợp không sử dụng cùng một mẫu phù hợp, chỉ trong một cấu trúc cú pháp khác nhau? – 9000
Biểu thức trường hợp có thể được nhúng vào một biểu thức khác, không nhất thiết phải là biểu thức đầu tiên của định nghĩa hàm. Tôi cho rằng các khai báo nhiều hàm với các mẫu chỉ là một đường cú pháp trên biểu mẫu thứ hai. – 9000