Это мой проект и продолжение моего предыдущего вопроса.

Haskell создает новые данные

Это основные части моего кода.

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]
0
william 9 Май 2016 в 18:22

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 должно быть ...?

0
ErikR 9 Май 2016 в 17:01
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]
0
william 9 Май 2016 в 17:05