Это мой проект и продолжение моего предыдущего вопроса.
Это основные части моего кода.
data Lukasiewicz = C | I | U
deriving (Eq, Show, Ord)
data LExpTree a = L a
| V [Char]
| N (LExpTree a)
| Q (LExpTree a)
| S (LExpTree a)
| K (LExpTree a)
| A ((LExpTree a), (LExpTree a))
| O ((LExpTree a), (LExpTree a))
| E ((LExpTree a), (LExpTree a))
| M ((LExpTree a), (LExpTree a))
deriving (Show, Eq)
type Dict = [(String, Lukasiewicz)]
type Unary a b = a -> b
type Unary2 a = a -> a
type Binary b = b -> b -> b
fold :: LExpTree a -> Unary a b -> Unary [Char] b -> Unary2 b -> Unary2 b -> Unary2 b -> Unary2 b -> Binary b -> Binary b -> Binary b -> Binary b -> b
fold (L x) l v n q s k a o e m = l x
fold (V x) l v n q s k a o e m = v x
fold (N x) l v n q s k a o e m = n (fold x l v n q s k a o e m)
fold (Q x) l v n q s k a o e m = q (fold x l v n q s k a o e m)
fold (S x) l v n q s k a o e m = s (fold x l v n q s k a o e m)
fold (K x) l v n q s k a o e m = k (fold x l v n q s k a o e m)
fold (A x) l v n q s k a o e m = a (fold (left' x) l v n q s k a o e m) (fold (right' x) l v n q s k a o e m)
fold (O x) l v n q s k a o e m = o (fold (left' x) l v n q s k a o e m) (fold (right' x) l v n q s k a o e m)
fold (E x) l v n q s k a o e m = e (fold (left' x) l v n q s k a o e m) (fold (right' x) l v n q s k a o e m)
fold (M x) l v n q s k a o e m = m (fold (left' x) l v n q s k a o e m) (fold (right' x) l v n q s k a o e m)
evalT :: Dict -> LExpTree Lukasiewicz -> Lukasiewicz
evalT xs x = fold x id (lk xs) negation possible sure unknown (<&>) (<|>) (<->) (-->)
Последняя функция evalT
примет Dict
и Expression Tree
и выдаст результат этого выражения при условии, что пользователь предоставит значение для всех переменных для V [Char]
в дерево выражений в списке Dict
.
Теперь мне нужно создать новую функцию, которая будет оценивать дерево выражений. На этот раз на входе не будет Dict
. Итак, вывод - это не результат, а список всех имен переменных.
Моя идея состоит в том, чтобы использовать ту же функцию fold
и игнорировать все, кроме V [Char]
. Остальные должны просто вызывать дерево выражений и больше ничего делать не должны.
Но понятия не имею, с чего начать.
Подпись функции должна быть
varList :: LExpTree Lukasiewicz -> [String]
2 ответа
Обычный способ записи varList
выглядит так:
varList (V x) = [x]
varList (L _) = []
varList (N e) = varList e -- same for all unary nodes, e.g. Q, S, K, ...
varList (A a b) = varList a ++ varList b
-- same for the other binary nodes
Так что сравните:
fold (N x) l v n q s k a o e m = n (fold x l v n q s k a o e m)
varList (N x) = varList x
Убедите себя, что:
varList blah == fold blah l v n ... e m
С этим отождествлением
varList x == n (fold x l v n ... e m) == n (varList x)
И поэтому n
должен быть id
, тождественной функцией.
Другой пример ... определение l
:
varList (L x) == fold (L x) l ... e m
== l (fold x l ... e m)
== l (varList x)
== []
Так что l (varList x) == []
, что означает, что l
должно быть ...?
fold2 :: LExpTree a -> [String]
fold2 (L x) = []
fold2 (V x) = [x]
fold2 (N x) = fold2 (x)
fold2 (Q x) = fold2 (x)
fold2 (S x) = fold2 (x)
fold2 (K x) = fold2 (x)
fold2 (A x) = (fold2 (left' x)) ++ (fold2 (right' x))
fold2 (O x) = (fold2 (left' x)) ++ (fold2 (right' x))
fold2 (E x) = (fold2 (left' x)) ++ (fold2 (right' x))
fold2 (M x) = (fold2 (left' x)) ++ (fold2 (right' x))
varList :: LExpTree Lukasiewicz -> [String]
varList x = [y | y <- fold2 x]
Похожие вопросы
Связанные вопросы
Новые вопросы
haskell
Haskell — это чисто функциональный язык программирования со строгой статической типизацией, отложенными вычислениями, обширной поддержкой параллелизма и параллелизма, а также уникальными возможностями абстракции.