from math import pi,sin,sqrt;
from functools import partial;
def fFormat(x):
return ':{0:.3f}'.format(x);
def output(tpl):
(v,s)=tpl;
if s=='': s+='<empty>';
print('y'+fFormat(v)+' # '+s,'\n');
def fSin(x):
return sin(x);
def fSqrt(x):
return sqrt(x);
def fCompoSinSqrt(x):
return sin(sqrt(x));
def fCompo(x,f):
return f(x);
def wSin(x):
y=fSin(x);
s=fFormat(y);
return(y,s);
def wSqrt(x):
y=fSqrt(x);
s=fFormat(y);
return(y,s);
def wComp_wSin_wSqrt(x):
(y1,s1)=wSqrt(x);
(y2,s2)=wSin(y1);
return (y2,s2+s1);
def mBind(xs:tuple,wf)->tuple:
assert isinstance(xs,tuple);
(x,s1)=xs;
(y,s2)=wf(x);
return (y,s2+s1);
def mUnit(x)->tuple:
return (x,'');
def mLift(x,f):
return mUnit(f(x));
def fSquare(x):
return x*x;
wSquare=partial(mLift,
f=fSquare);
def dLift(f):
def lift(x):
v=f(x);
s=fFormat(v);
return (v,s);
return lift;
@dLift
def dSqrt(x):
return sqrt(x);
if __name__ == '__main__':
print('\n# Beginning...');
if False:
x=pi/2; y=wSin(x); output(y);
x=2; y=wSqrt(x); output(y);
x=2; y=wComp_wSin_wSqrt(x); output(y);
x=2; y=fCompo(fCompo(x,fSqrt),fSin); print(y);
x=2;
y=mBind(mBind(mUnit(x),wSqrt),wSin);
assert(str(y)=="(0.9877659459927356, ':0.988:1.414')");
y=mBind(mBind(mUnit(x),wSqrt),lambda z : (z*z,fFormat(z*z)));
assert(str(y)=="(2.0000000000000004, ':2.000:1.414')");
y=mBind(mBind(mBind(mUnit(x),wSqrt),wSqrt),wSqrt);
assert(str(y)=="(1.0905077326652577, ':1.091:1.189:1.414')");
x=2;
assert(mBind(mUnit(x),wSqrt)==wSqrt(x));
assert(mBind(mUnit(x),mUnit)==mUnit(x));
y1=mBind(mBind(mUnit(x),wSqrt),wSin);
y2=mBind(mUnit(x),lambda z : mBind(wSqrt(z),wSin));
assert(y1==y2);
x=2;
y=wSquare(x);
assert(str(y)=="(4, '')");
x=2;
y=mBind(mUnit(x),dSqrt);
y=mBind(y,wSin);
assert(str(y)=="(0.9877659459927356, ':0.988:1.414')");
print('\n# Finished\n');