Tôi đang cố gắng giải quyết vấn đề về khung cân bằng. Tôi không muốn làm IO liên tục, và thay vì sẽ thực hiện một cuộc gọi duy nhất để getLine và phân tích chuỗi kết quả. Do đó, hàm giải quyết vấn đề sẽ xử lý hai trạng thái khác nhau: Phần không được thêm vào của chuỗi đầu vào và ngăn xếp khung.Làm các chức năng đơn thuần bình thường hoạt động với máy biến áp đơn nguyên tương đương
tôi muốn thiết lập một số chức năng cho thao tác một chồng:
type Stack = String
pop :: Stack -> (Char,Stack)
pop (x:xs) = (x,xs)
push :: Char -> Stack -> ((),Stack)
push a xs = ((),a:xs)
Đó là tất cả tốt nếu tôi hoạt động trong các đơn nguyên nhà nước, tuy nhiên tôi đang hoạt động trong các đơn nguyên StateT
balanced :: StateT Stack (State String) Bool
Tôi biết tôi đã được yêu cầu không có các bản sao đơn lẻ trong ngăn xếp. Tôi đang làm theo cách này bởi vì tôi thích cách đơn giản hóa các định nghĩa push và pop.
Hai vấn đề:
- Không có vấn đề gì tôi làm tôi không thể tìm thấy một cách để áp dụng push và pop đến stack chứa trong StateT.
- Tôi không có ý tưởng làm thế nào để gọi đây là từ chức năng chính
Dưới đây là phần còn lại của mã
next :: String -> (Maybe Char,String)
next "" = (Nothing,[])
next (x:xs) = (Just x,xs)
balanced = do
c <- lift (state next)
case c of
Nothing -> return True
Just c -> if elem c open
then (push c) >> balanced
else if elem c close
then pop >>= \x ->
if eq x c
then balanced
else return False
else balanced
where open = "<{(["
close = "])}>"
eq '(' ')' = True
eq '{' '}' = True
eq '<' '>' = True
eq '[' ']' = True
eq _ _ = False
Thử sử dụng 'Chuỗi đầu đọc' thay vì' Chuỗi trạng thái' cho đơn vị bên trong. – dflemstr