Các loại chữ ký cho *>
nói nó trả về kết quả từ thứ hai phân tích cú pháp, và ném đi những kết quả từ phân tích cú pháp đầu tiên. Do đó, email
chỉ trả lại kết quả từ trình phân tích cú pháp cuối cùng trong chuỗi.
Những gì bạn có thể muốn là một cái gì đó giống như
email =
stitch
<$> many1 alphaNum
<*> char '@'
<*> many1 alphaNum
<*> string ".com"
này chạy bốn parsers và chuyển kết quả của từng như một cuộc tranh cãi để stitch
. Nếu bạn viết triển khai phù hợp cho stitch
:
stitch a b c d = a ++ [b] ++ C++ d
thì bạn sẽ lấy lại chuỗi của mình.
Chú ý rằng vào thời điểm này, bạn cũng có thể đặt tên người dùng và miền vào các lĩnh vực riêng biệt của một cấu trúc dữ liệu hoặc một cái gì đó:
data Email = Email {username, domain :: String}
email =
Email
<$> many1 alphaNum
<* char '@'
<*> ((++) <$> many1 alphaNum <*> string ".com")
Bây giờ phân tích cú pháp của bạn trả về một cấu trúc Email
chứ không phải chỉ là một chuỗi đồng bằng. Đó có thể không phải là những gì bạn đang theo dõi, nhưng nó thể hiện cách viết một trình phân tích cú pháp phức tạp hơn.
Tất cả điều này là sử dụng giao diện Applicative
cho Parsec, thường được coi là kiểu tốt. Các cách nào khác để sử dụng Parsec là giao diện Monad
:
email = do
a <- many1 alphaNum
b <- char '@'
c <- many1 alphaNum
d <- string ".com"
return (a ++ [b] ++ C++ d)
Đây có phải là con đường thành ngữ để hoàn thành nhiệm vụ nói? Tôi sẽ không sử dụng mã sản xuất ở bất cứ đâu. Tôi chỉ đơn giản là cố gắng để tìm hiểu parsec. – Jay
Cả hai cách đều thành ngữ – nponeccop