Khi xử lý các kiểu dữ liệu đại số lớn trong Haskell, có một quá trình truyền đệ quy cụ thể không được chụp bằng cách gấp trên kiểu dữ liệu. Ví dụ, giả sử tôi có một kiểu dữ liệu đơn giản đại diện cho công thức trong logic mệnh đề, và một lần được xác định trên nó:Truy nhập ngược từ dưới lên đệ quy của các kiểu dữ liệu đại số
type FAlgebra α φ =
(φ, φ, -- False, True
α -> φ, -- Atom
φ -> φ, -- Negation
φ -> φ -> φ, -- Conjunction
φ -> φ -> φ, -- Disjunction
φ -> φ -> φ, -- Implication
φ -> φ -> φ) -- Bi-implication
fold :: FAlgebra α φ -> Form α -> φ
fold (f,t,lit,not,con,dis,imp,iff) = fold' where
fold' (Fls) = f
fold' (Tru) = t
fold' (Lit α) = lit α
fold' (Not φ) = not (fold' φ)
fold' (Con φ ψ) = con (fold' φ) (fold' ψ)
fold' (Dis φ ψ) = dis (fold' φ) (fold' ψ)
fold' (Imp φ ψ) = imp (fold' φ) (fold' ψ)
fold' (Iff φ ψ) = iff (fold' φ) (fold' ψ)
chương trình đệ quy này cung cấp một câu trả lời ngắn gọn để recursions như đánh giá hoặc tìm literals:
eval :: (Ord α) => Map α Bool -> Form α -> Bool
eval v = fold (False, True, (fromJust . flip M.lookup v),
not, (&&), (||), ((||) . not), (==))
literals :: (Ord α) => Form α -> Set α
literals = fold (S.empty, S.empty, S.singleton, id,
S.union, S.union, S.union, S.union)
Tuy nhiên, nó không quá tốt khi tôi muốn "quét" loại dữ liệu. Trong phần sau, simp là một hàm phụ được xác định bởi khớp mẫu phù hợp:
simplify :: Form α -> Form α
simplify (Not φ) = simp (Not (simplify φ))
simplify (Con φ ψ) = simp (Con (simplify φ) (simplify ψ))
simplify (Dis φ ψ) = simp (Dis (simplify φ) (simplify ψ))
simplify (Imp φ ψ) = simp (Imp (simplify φ) (simplify ψ))
simplify (Iff φ ψ) = simp (Imp (simplify φ) (simplify ψ))
simplify φ = φ
Sử dụng một lần để xác định đơn giản, tất nhiên, tạo ra kết quả không chính xác. Ví dụ, sau đây không phải là tương đương:
simplify = fold (Fls, Tru, Lit, (simp . Not), con Con, con Dis, con Imp, con Iff)
where con f φ ψ = simp (f φ ψ)
giải pháp tốt nhất để recursions như là gì đơn giản hóa? Tôi có nên xác định một traversal chung tương tự như gấp trên các loại dữ liệu, hoặc là có một mô hình đệ quy chuẩn để xác định các chức năng như vậy?
Chỉ trong trường hợp, vui lòng thêm liên kết vào giấy. –
@Yasir: Đã thêm. Tôi tìm thấy một liên kết không trả tiền làm việc. – nominolo
Bạn chỉ có thể thêm liên kết dưới dạng nhận xét, trong trường hợp bạn thay đổi ý định và cập nhật câu hỏi với dữ liệu hữu ích hơn sau này (có thể thêm liên kết). Bằng cách này bạn sẽ không nhận được câu trả lời của bạn nhận được CWed. :-) –