khi bạn chia danh sách bằng cách sử dụng cú pháp x: xs tại sao nó được bao trong dấu ngoặc đơn? ý nghĩa của dấu ngoặc đơn là gì? tại sao không [x: xs] hoặc chỉ x: xs?Dấu ngoặc đơn biểu thị trong (x: xs) khi khớp mẫu là gì?
Trả lời
Các tế bào khuyết điểm không phải ngoặc trong mọi bối cảnh, nhưng trong hầu hết các tình huống đó là vì
ứng dụng Chức năng liên kết chặt chẽ hơn so với bất kỳ nhà điều hành ghi.
Đốt nó vào não của bạn bằng các chữ cái cháy.
Ví dụ:
length [] = 0
length (x:xs) = 1 + length xs
Nếu ngoặc đã được bỏ qua các trình biên dịch sẽ nghĩ rằng bạn đã có một cuộc tranh cãi x
tiếp theo là một nhà điều hành ghi ill-đặt, và nó sẽ phàn nàn cay đắng. Mặt khác đây là OK
length l = case l of [] -> 0
x:xs -> 1 + length xs
Trong trường hợp này không phải x
cũng không xs
có thể có thể được hiểu như là một phần của một ứng dụng chức năng như vậy không có dấu ngoặc đơn là cần thiết.
Lưu ý rằng cùng tuyệt vời quy tắc ứng dụng chức năng gắn kết chặt chẽ hơn so với bất kỳ nhà điều hành ghi là những gì cho phép chúng ta viết length xs
trong 1 + length xs
mà không cần bất kỳ dấu ngoặc đơn. Quy tắc infix giveth và quy tắc infix bỏ đi.
+1 cho các chữ cái cháy. Mã Haskell của tôi dừng lại trông giống như Lisp sau khi tôi tiếp thu quy tắc này. – Nefrubyr
+1. Yêu câu cuối cùng –
Bạn chỉ cần sử dụng toán tử cons :
, ưu tiên thấp. Dấu ngoặc đơn là cần thiết để mọi thứ ở bên phải.
Và bạn không sử dụng [x:xs]
, vì điều đó sẽ khớp với danh sách có phần tử duy nhất là danh sách có đầu x
và đuôi xs
.
Tôi chưa từng thử mẫu '[x: xs]' cụ thể nào, nhưng tất nhiên là bạn đúng; nó khớp với một danh sách singleton ở cấp cao nhất. Ký hiệu desugared của pattern sẽ là: '((x: xs): [])'. –
Tôi không biết câu trả lời chính xác, nhưng tôi đoán đó là do những gì có thể được so khớp trong các mẫu. Chỉ các nhà xây dựng mới có thể được so khớp. Các nhà xây dựng có thể là từ đơn hoặc tổng hợp. Xem mã tiếp theo:
data Foo = Bar | Baz Int
f :: Foo -> Int
f Bar = 1
f (Baz x) = x - 1
Từ đơn lẻ khớp với nhau. Nhưng các nhà xây dựng tổng hợp phải được bao quanh với các parens để tránh sự mơ hồ. Nếu chúng ta bỏ qua Parens có vẻ như phù hợp với hai lập luận độc lập:
f Baz x = x - 1
Vì vậy, như (:)
là composit nó phải nằm trong dấu ngoặc. Bỏ qua parens cho Bar
là một loại đường cú pháp.
CẬP NHẬT: Tôi nhận ra rằng (như sykora đã lưu ý) đó là hậu quả của quyền ưu tiên của toán tử. Nó làm rõ các giả định của tôi. Ứng dụng chức năng (chỉ là không gian giữa hàm và đối số) có ưu tiên cao nhất. Những người khác bao gồm (:) có quyền ưu tiên thấp hơn. Vì vậy, f x:xs
sẽ được hiểu là ((:) (f x)) xs
có lẽ không phải là những gì chúng tôi cần. Trong khi f (x:xs)
được hiểu là f
được áp dụng cho x:xs
, lần lượt là (:)
được áp dụng cho x
và xs
.
Đó là việc cần làm với phân tích cú pháp.
Hãy nhớ rằng, dấu hai chấm: chỉ là một hàm tạo được viết bằng cú pháp toán tử. Vì vậy, một chức năng như
foo [] = 0
foo (x:xs) = x + foo xs
cũng có thể được viết như
foo [] = 0
foo ((:) x xs) = x + foo xs
Nếu bạn thả ngoặc ở chỗ dòng cuối cùng, nó trở nên rất khó để phân tích!
:
là một hàm tạo dữ liệu, giống như bất kỳ đối sánh mẫu nào khác, nhưng được in bằng văn bản. Các dấu ngoặc đơn hoàn toàn là do có ưu tiên infix; chúng thực sự không bắt buộc và có thể được bỏ qua một cách an toàn khi các quy tắc ưu tiên cho phép. Ví dụ:
> let (_, a:_) = (1, [2, 3, 4]) in a
2
> let a:_ = "xyzzy"
'x'
> case [1, 2, 3] of; a:b -> a; otherwise -> 0;
1
Điều thú vị là dường như không hoạt động trong đầu lambda. Không chắc chắn lý do tại sao. Như mọi khi, toán tử "juxtaposition" liên kết chặt chẽ hơn bất kỳ thứ gì khác, vì vậy thường không phải là dấu phân tách là cần thiết, nhưng chúng không thực sự là phần của kết hợp mẫu - nếu không bạn sẽ không thể sử dụng các mẫu như (x:y:zs)
thay vì (x:(y:zs))
.
- 1. Mẫu Jinja hiển thị dấu ngoặc kép hoặc dấu nháy đơn là ' "
- 2. Xóa văn bản trong dấu ngoặc đơn (dấu ngoặc đơn trong dấu ngoặc đơn)
- 3. Dấu ngoặc đơn sau dấu ngoặc nhọn có nghĩa là gì?
- 4. Tên "xs" cho khớp mẫu đến từ đâu?
- 5. C# Regex khớp với bất kỳ thứ gì bên trong dấu ngoặc đơn
- 6. Dấu ngoặc và dấu ngoặc đơn sau bộ chọn jquery nghĩa là gì?
- 7. Ghép cặp dấu ngoặc nhọn, dấu ngoặc đơn và dấu ngoặc đơn
- 8. Biểu thức \ X khớp với nhau khi ở trong RegEx?
- 9. Sự khác biệt giữa dấu nháy đơn và dấu ngoặc kép trong Perl là gì?
- 10. Sự khác nhau giữa dấu nháy đơn và dấu ngoặc kép trong Perl là gì?
- 11. Sự khác nhau giữa dấu nháy đơn và dấu ngoặc kép trong SQL là gì?
- 12. Ý nghĩa của dấu nháy đơn so với dấu ngoặc kép trong so sánh là gì?
- 13. Làm cách nào để khớp văn bản trong dấu ngoặc đơn bằng regex?
- 14. Nội dung bên trong dấu ngoặc đơn trong @interface và @implementation có nghĩa là gì?
- 15. Đi tới dấu ngoặc đơn phù hợp
- 16. So khớp mẫu Haskell - nó là gì?
- 17. Chọn văn bản bên trong dấu ngoặc đơn từ bên ngoài dấu ngoặc đơn trong Vim
- 18. Những dấu ngoặc vuông này trong Haskell là gì?
- 19. Điều gì sẽ xảy ra nếu(); làm gì, trong đó dấu chấm phẩy là ngay sau dấu ngoặc đơn?
- 20. Cụm từ thông dụng khớp với một dấu ngoặc vuông là gì?
- 21. Dấu ngoặc nhọn/dấu ngoặc rỗng có nghĩa là gì trong Java?
- 22. Sự khác biệt giữa các danh sách được bao quanh bởi dấu ngoặc vuông và dấu ngoặc đơn trong Python là gì?
- 23. Dấu ngoặc đơn trong khai báo biến C có nghĩa là gì?
- 24. bash: double vs dấu ngoặc đơn trong đánh giá biểu thức kiểm tra tệp
- 25. Xóa các dấu ngoặc đơn trong json?
- 26. Cách thoát dấu ngoặc đơn trong grep
- 27. Xác định nội dung hàm bash bằng dấu ngoặc đơn thay vì dấu ngoặc đơn
- 28. Bản sao kê mẫu và Khớp mẫu
- 29. Lệnh nào khớp với các dấu ngoặc trong Emacs?
- 30. Đổi tên nhiều tệp mà không cần dấu ngoặc đơn/xóa dấu ngoặc đơn windows
Bạn có ví dụ về vị trí được gói trong() không? x: xs có thể được sử dụng để mô tả danh sách có phần tử đầu tiên của danh sách. [x: xs] sẽ là danh sách có danh sách x: xs trong đó. –
Ông nói về sự phù hợp với mô hình, không phải về việc xây dựng danh sách. – Rorick