하스켈에서 대수 데이터 형식을 처리 할 때 데이터 형식을 통해 접을 때 특정 재귀 적 탐색이 캡처되지 않습니다.대수 데이터 형식의 상향식 상향 탐색
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)
:
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' ψ)
이 재귀 방식 평가 또는 발견 리터럴 같은 재귀에 대한 간결한 대답을 제공합니다 : 예를 들어, 내가 명제 논리의 수식을 나타내는 간단한 데이터 유형 및 그 위에 정의 된 배를 가정
그러나 데이터 형식을 "스윕"하고 싶을 때는 너무 좋지 않습니다.
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 φ = φ
물론, 잘못된 결과를 생성 단순화 정의 접힘 사용 : 이하, SIMP 필요한 패턴 매칭에 의해 정의 된 보조 기능이다.
simplify = fold (Fls, Tru, Lit, (simp . Not), con Con, con Dis, con Imp, con Iff)
where con f φ ψ = simp (f φ ψ)
같은 재귀에 최적의 솔루션이을 단순화 무엇입니까 : 예를 들어, 다음은 동일하지 않습니다? 데이터 유형에 대한 fold와 비슷한 generic traversal을 정의해야합니까? 아니면 그러한 함수를 정의하기위한 표준 재귀 패턴이 있습니까?
경우에 따라 용지에 링크를 추가하십시오. –
@ 야시 르 : 추가됨. 작동하지 않는 유료 링크를 찾았습니다. – nominolo
마음이 바뀌고 나중에 더 유용한 데이터로 질문을 업데이트하는 경우 (링크 추가 가능성이 있음) 대비하여 링크를 덧글로 추가하면됩니다. 이렇게하면 답을 얻을 수 없을 것입니다. :-) –