銀行口座その3:共同口座と問題3.7
C++11でもSchemeでも見づらくて気持ち悪い、という経験をしたが、
たしかにそれはバグの温床だわな。
普段のプログラムでも、オブジェクトをコロコロ変更すると訳がわからなくなるので、
なるべく一度インスタンス化したオブジェクトは変えないようなスタイルを、
なんとなく意識していたが、それが正しいのだ、ということ。
ただ、そうできたのは、そうできる問題に対することが多かったから、
ということにすぎない。データベースとか扱ったときはだいぶ混乱したこともある。
その辺をどう頑健にしていくかが3章の一つのテーマなのかな。
問題3.8はSchemeの話なのでパス。
----
const
function<List(List)> returnErrorMessage
=[](const
List& Dummy){
return(makeLeaf("Incorrect
password"));
};
const
function<List(List)> returnErrorMonitored
(makeMonitored(makeLeaf(returnErrorMessage)));
const
function<List(List)> callTheCops
=[](const
List& Dummy){
return(makeLeaf("The cops are
called."));
};
const
function<List(List)> processError(const List& limitCount)
{
if(returnErrorMonitored
(makeLeaf("how-many-calls?"))>=limitCount-makeLeaf(1))
{return(callTheCops);}
return(returnErrorMonitored);
}
const
function<function<List(List)>(List,List)> makeAccount
(const List&
balanceIn, const List& passwdIn)
{
const List&& balance(std::move(balanceIn));
const List&&
passwd(std::move(passwdIn));
const List limitCount(makeLeaf(7));
const function<List(List)> withdraw
=[balance](const List& amount){
if(balance>=amount){
setInsert(balance-amount,balance);
return(balance);
}
return(makeLeaf("Insuffcient
funds"));
};
const function<List(List)> deposit
=[balance](const List& amount){
setInsert(balance+amount,balance);
return(balance);
};
const
function<function<List(List)>(void)> processErrorMessage
=[limitCount](void){
return(processError(limitCount));
};
const
function<function<List(List)>(List,List)> dispatch=
[withdraw,deposit,processErrorMessage,passwd,limitCount]
(const List& passwdInput, const
List& message){
if(isEq(message,makeLeaf("error"))
||!isEq(passwd,passwdInput)){return(processErrorMessage());}
returnErrorMonitored(makeLeaf("reset-count"));
if(isEq(message,makeLeaf("withdraw"))){return(withdraw);}
if(isEq(message,makeLeaf("deposit"))){return(deposit);}
cerr<<"Unknown request ---
MAKE-ACCOUNT"<<endl;
exit(1);
return(function<List(List)>([](const
List& i){return(makeList());}));
};
return(dispatch);
}
const
function<function<List(List)>(List,List)> makeJoint
(const
function<function<List(List)>(List,List)>& oldAccountIn,
const List& oldPasswdIn, const List&
jointAccountPasswdIn)
{
const
function<function<List(List)>(List,List)>&&
oldAccount(std::move(oldAccountIn));
const List&&
oldPasswd(std::move(oldPasswdIn));
const List&&
jointAccountPasswd(std::move(jointAccountPasswdIn));
const
function<function<List(List)>(List,List)> dispatch
=[oldAccount,oldPasswd,jointAccountPasswd]
(const List& passwdInput, const
List& message){
if(!isEq(jointAccountPasswd,passwdInput)){
return(oldAccount(makeLeaf(""),makeLeaf("error")));
}
return(oldAccount(oldPasswd,message));
};
return(dispatch);
}
int main(int argc,
char** argv)
{
cout<<"Excersize 3.7:"<<endl;
const auto peterAccount
(makeAccount(makeLeaf(100),makeLeaf("open-sesame")));
cout<<"peter-acc = (make-account
100 'open-sesame)"<<endl;
cout<<"((peter-acc 'open-sesame
'withdraw) 40) = "
<<listString(peterAccount
(makeLeaf("open-sesame"),
makeLeaf("withdraw"))(makeLeaf(40)))<<endl;
cout<<"((peter-acc 'hirake-goma
'deposit) 40) = "
<<listString(peterAccount
(makeLeaf("hirake-goma"),
makeLeaf("deposit"))(makeLeaf(40)))<<endl;
const auto paulAccount
(makeJoint(peterAccount,
makeLeaf("open-sesame"),makeLeaf("rosebud")));
cout<<endl<<"paul-acc =
(make-joint peter-acc 'open-sesame 'rosebud)"<<endl;
cout<<"((paul-acc 'rosebud
'withdraw) 40) = "
<<listString(paulAccount
(makeLeaf("rosebud"),
makeLeaf("withdraw"))(makeLeaf(40)))<<endl;
cout<<"((paul-acc 'open-sesame
'deposit) 40) = "
<<listString(paulAccount
(makeLeaf("open-sesame"),
makeLeaf("deposit"))(makeLeaf(40)))<<endl;
cout<<"((paul-acc 'rosebud
'deposit) 100) = "
<<listString(paulAccount
(makeLeaf("rosebud"),
makeLeaf("deposit"))(makeLeaf(100)))<<endl;
cout<<"((peter-acc 'open-sesame
'deposit) 40) = "
<<listString(peterAccount
(makeLeaf("open-sesame"),
makeLeaf("deposit"))(makeLeaf(40)))<<endl;
return(0);
}
----
出力
----
Excersize 3.7:
peter-acc =
(make-account 100 'open-sesame)
((peter-acc
'open-sesame 'withdraw) 40) = 60
((peter-acc
'hirake-goma 'deposit) 40) = Incorrect password
paul-acc =
(make-joint peter-acc 'open-sesame 'rosebud)
((paul-acc
'rosebud 'withdraw) 40) = 20
((paul-acc
'open-sesame 'deposit) 40) = Incorrect password
((paul-acc
'rosebud 'deposit) 100) = 120
((peter-acc
'open-sesame 'deposit) 40) = 160
0 件のコメント :
コメントを投稿