変換を行って、我々は次の方法で会社の階層を表しているとしますは、多型の構造を横断し、ほんの数例で
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
import Data.Generics.Aliases
import Data.Generics.Schemes
data CompanyAsset = Employee Name Salary
| Plant Name
| Boss Name Performance Salary [CompanyAsset]
| Pet Name
| Car Id
| Guild [CompanyAsset]
| Fork CompanyAsset CompanyAsset
-- ... and imagine 100 more options that recursively use `CompanyAsset`.
deriving (Show, Data)
-- Performance of the department.
data Performance = Good | Bad deriving (Show, Data)
type Name = String
type Id = Int
newtype Salary = Salary Double deriving (Show, Data, Typeable)
raise :: Salary -> Salary
そして、私はそうではない会社の資産の給与を上げる機能をdefneしたいと思います部門がBad
のパフォーマンスを持つ祖先Boss
を持っている次のような機能を簡単に定義することができます。
raiseSalaries :: CompanyAsset -> CompanyAsset
raiseSalaries (Boss n Good s as) = Boss n Good (raise s) (raiseSalaries <$> as)
raiseSalaries [email protected](Boss _ Bad _ _) = a -- The salaries of everything below are not raised if the performance is 'Bad'
raiseSalaries ... -- and from here onwards we have **boilerplate**!
問題は、これが(議論のために、CompanyAsset
が指定されており、変更することができないことを前提としてください)定型の多くを必要とすることです。
私の質問は、上記の定型句を避けることができるような方法でデータ構造をトラバースする方法があるかどうかです。
この質問はsimilar oneに関連していますが、この場合はeverywhere'
を使用しても給与を引き上げるべきではない場合があるので、助けになりません。