従業員データベースの構築と問題2.74
辞書的にはInsatiable
enterprises, Inc.=「強欲社」とかなるか。
飽くことのない欲望という意味でアキナイ社という訳なのかな、飽きないと申しますし。
事業所名を型タグとして各従業員レコードに割り振って、
型ごとに情報を取り出す関数を自律制御させるわけで、、
つまりは複素数や問題2.73とあまり変わらない。
しかも集合の生成や要素探索は、すでに2.3.3節でひと通りのツールが出揃っているので、
思ったよりも楽。んで東京事業所とEU事業所を作り、
東京事業所は木で、EU事業所はリストで名簿を作ってあることにしたが、
それだけだとlookupが強力すぎて実装が変わらないので、
さらに、東京事業所はデータを従業員名キーで律儀にソートしてあるが、
EU事業所はソートしていないことにした。
問題2.74bでget-recordの結果をさらに自律処理させるために、
get-recordが事業所情報も返さなければならない。
それにはlookupでヒットした事業所レコードに、事業所タグを付け直せば良い。
なおEU事業所の名簿で、ローマのカトーは本当はCatoだが、
加藤清正とダブらせるためにあえてKatoで押す。
----
typedef
List Record;
typedef
List BranchData;
typedef
List HeadQuarterRecord;
class
InsatiableInc{
public:
InsatiableInc(const TagType
tagIn):tagString(tagIn){}
virtual ~InsatiableInc(void){};
const TagType
getTag(void)const{return(this->tagString);}
virtual const Record getRecord
(const BranchData&,const
string&)const=0;
virtual const int getSalary(const
HeadQuarterRecord&)const=0;
virtual const HeadQuarterRecord tag
(const BranchData& branchData)const
{return(attachTag(this->getTag(),branchData));}
private:
const TagType tagString;
};
class
TokyoBranch:public InsatiableInc{
public:
TokyoBranch(void):InsatiableInc("Tokyo"){
put("get-record",this->getTag(),
makeLeaf(function<Record(BranchData,string)>
([this](const BranchData& branchData,
const string& name)
{return(this->getRecord(branchData,name));})));
put("get-salary",this->getTag(),
makeLeaf(function<int(HeadQuarterRecord)>
([this](const HeadQuarterRecord&
record)
{return(this->getSalary(record));})));
}
const HeadQuarterRecord getRecord(const
BranchData& branchList,
const string& name)const override
{return(this->tag(lookup(name,branchList)));}
const int getSalary(const
HeadQuarterRecord& record)const override
{
if(isNull(cdr(record))){return(0);}
return(value<int>(cadadr(record)));
}
};
class
EUBranch:public InsatiableInc{
public:
EUBranch(void):InsatiableInc("EU"){
put("get-record",this->getTag(),
makeLeaf(function<Record(BranchData,string)>
([this](const BranchData& branchData,
const string& name)
{return(this->getRecord(branchData,name));})));
put("get-salary",this->getTag(),
makeLeaf(function<int(HeadQuarterRecord)>
([this](const HeadQuarterRecord&
record)
{return(this->getSalary(record));})));
}
const HeadQuarterRecord getRecord(const
BranchData& branchList,
const string& name)const override
{return(this->tag(lookupUnordered(name,branchList)));}
const int getSalary(const
HeadQuarterRecord& record)const override
{
if(isNull(cdr(record))){return(0);}
return(value<int>(caddr(record)));
}
};
//---------abstraction
barrier---------
InsatiableInc*
_tokyoBranch(nullptr);
const
void installTokyoBranch(void){
_tokyoBranch=new TokyoBranch();
}
InsatiableInc*
_EUBranch(nullptr);
const
void installEUBranch(void){
_EUBranch=new EUBranch();
}
const
void uninstallBranches(void){
if(nullptr!=_tokyoBranch) delete
_tokyoBranch;
if(nullptr!=_EUBranch) delete _EUBranch;
}
//---------abstraction
barrier---------
const
string branch(const BranchData branchData)
{return(value<string>(car(branchData)));}
const
BranchData branchList(const BranchData& branchData)
{return(cdr(branchData));}
//
get-record
const
HeadQuarterRecord getRecord(const BranchData& branchData,
const string& name)
{
const List
recordFunLeaf(get("get-record",branch(branchData)));
if(isFunction(recordFunLeaf)){
const auto recordFun
(executable<Record,BranchData,string>(recordFunLeaf));
return(recordFun(branchList(branchData),name));
}
return(0);
}
//get-salary
const
int getSalary(const HeadQuarterRecord& record)
{
const List
salaryFunLeaf(get("get-salary",
value<TagType>(car(record))));
if(isFunction(salaryFunLeaf)){
const auto salaryFun
(executable<int,HeadQuarterRecord>(salaryFunLeaf));
return(salaryFun(cdr(record)));
}
return(0);
}
//---------abstraction
barrier---------
//find-employee-record
const
List findEmployeeRecord
(const
string& name,const List& allBranchList)
{
const
function<HeadQuarterRecord(BranchData)>
getEmployeeRecords
=[name](const BranchData&
branchRecord)
{return(getRecord(branchRecord,name));};
return(mapping(getEmployeeRecords,allBranchList));
}
//make
a list for Tokyo branch
const
List addTokyoBranchMember
(const
List& employeeList,
const string name, const string address, const
int salary)
{
return(adjoinSet(makeList(name,makeList(address,salary)),employeeList));
}
const
BranchData makeTokyoBranchEnployees(void){
if(_tokyoBranch==nullptr){return(makeList());}
List branchList(makeList());
if(_tokyoBranch!=nullptr){
branchList=addTokyoBranchMember
(branchList,"Oda","Nadoya",20000);
branchList=addTokyoBranchMember
(branchList,"Toyotomi","Osaka",30000);
branchList=addTokyoBranchMember
(branchList,"Tokugawa","Edo",30000);
branchList=addTokyoBranchMember
(branchList,"Takeda","Kofu",10000);
branchList=addTokyoBranchMember
(branchList,"Kato","Kumamoto",12000);
}
return(_tokyoBranch->tag(branchList));
}
//make
a list for EU branch
const
List addEUBranchMember
(const
List& employeeList,
const string name, const string address, const
int salary)
{
return(adjoinSetUnordered(makeList(name,address,salary),employeeList));
}
const
BranchData makeEUBranchEnployees(void){
if(_EUBranch==nullptr){return(makeList());}
List branchList(makeList());
if(_EUBranch!=nullptr){
branchList=addEUBranchMember
(branchList,"Arthur","London",30000);
branchList=addEUBranchMember
(branchList,"Napolleon","Paris",20000);
branchList=addEUBranchMember
(branchList,"Siegfried","Berlin",10000);
branchList=addEUBranchMember
(branchList,"Kato","Roma",15000);
branchList=addEUBranchMember
(branchList,"Felipe","Madrid",12000);
}
return(_EUBranch->tag(branchList));
}
int
main(int argc, char** argv)
{
installTokyoBranch();
const BranchData
tokyoBranchList(makeTokyoBranchEnployees());
installEUBranch();
const BranchData
EUBranchList(makeEUBranchEnployees());
cout<<"tokyo-branch =
"<<listString(tokyoBranchList)<<endl;
cout<<"EU-branch =
"<<listString(EUBranchList)<<endl;
cout<<endl;
const string name1("Toyotomi");
const HeadQuarterRecord
record1(getRecord(tokyoBranchList,name1));
cout<<"(get-record tokyo-branch
'"<<name1<<") = "
<<listString(record1)<<endl;
const string name2("Siegfried");
const HeadQuarterRecord
record2(getRecord(EUBranchList,name2));
cout<<"(get-record EU-branch
'"<<name2<<") = "
<<listString(record2)<<endl;
cout<<endl;
cout<<"(get-salary (get-record
Tokyo-branch '"<<name1<<")) = "
<<getSalary(record1)<<endl;
cout<<"(get-salary (get-record
EU-branch '"<<name2<<")) = "
<<getSalary(record2)<<endl;
cout<<endl;
const List
allBranchList(makeList(tokyoBranchList,EUBranchList));
cout<<"all-branch-list = (list
tokyo-branch EU-branch)"<<endl;
const string name3("Kato");
cout<<"(find-employee-record
"<<name3<<" all-branch-list) = "
<<listString(findEmployeeRecord(name3,allBranchList))<<endl;
uninstallBranches();
return(0);
}
----
出力
----
tokyo-branch
= ('Tokyo ('Kato ('Kumamoto 12000)) ('Oda ('Nadoya 20000)) ('Takeda ('Kofu
10000)) ('Tokugawa ('Edo 30000)) ('Toyotomi ('Osaka 30000)))
EU-branch
= ('EU ('Felipe 'Madrid 12000) ('Kato 'Roma 15000) ('Siegfried 'Berlin 10000)
('Napolleon 'Paris 20000) ('Arthur 'London 30000))
(get-record
tokyo-branch 'Toyotomi) = ('Tokyo 'Toyotomi ('Osaka 30000))
(get-record
EU-branch 'Siegfried) = ('EU 'Siegfried 'Berlin 10000)
(get-salary
(get-record Tokyo-branch 'Toyotomi)) = 30000
(get-salary
(get-record EU-branch 'Siegfried)) = 10000
all-branch-list
= (list tokyo-branch EU-branch)
(find-employee-record
Kato all-branch-list) = (('Tokyo 'Kato ('Kumamoto 12000)) ('EU 'Kato 'Roma
15000))
0 件のコメント :
コメントを投稿