Я плохо знаком с Haskell, таким образом, я пытаюсь выяснить, как сделать обходы дерева.
Вот пример Компании (с небольшим изменением), что я видел в нескольких газетах
data Company = C [Dept] deriving (Eq, Show, Typeable, Data)
data Dept = D Name Manager [Unit] deriving (Eq, Show, Typeable, Data)
data ThinkTank= TK Name [Unit] deriving (Eq, Show, Typeable, Data)
data Unit = PU Employee | DU Dept deriving (Eq, Show, Typeable, Data)
data Employee = E Person Salary deriving (Eq, Show, Typeable, Data)
data Person = P Name Address deriving (Eq, Show, Typeable, Data)
data Salary = S Float deriving (Eq, Show, Typeable, Data)
type Manager = Employee
type Name = String
type Address = String
То, что я хотел бы сделать, переместить Сотрудника от того, где он к конкретному отделу. Этот человек мог быть в Отделе или ThinkTank.
Кажется легким сделать вещи в SYB, пока Вы делаете один тип, но я не уверен, как иметь дело с несколькими типами данных.
Вам нужно будет начать с учебника SYB,
Основные функции обхода:
Поиграйте с ними, чтобы разобраться в API, и вы все решите.
Дженерики SYB - это немного больше, чем просто упражнение на Haskell для новичков.
Не слишком хорошо знаком с SYB, поэтому я покажу пример с использованием uniplate. Пример только удаляет подразделение сотрудника из его отдела или аналитического центра, но вы, вероятно, легко поймете, как расширить его, чтобы сделать то, что вы хотите.
> let jack = E (P "Jack" "The Road") (S 7)
> import Data.Generics.Uniplate.Data
> transformBi (filter (/= PU jack)) $ C [D "Operations" (E (P "Charles" "Seattle") (S 700000)) [PU jack]]
C [D "Operations" (E (P "Charles" "Seattle") (S 700000.0)) []]