Mark Seemanãé¢æ°åããã°ã©ãã³ã°ã«ã€ããŠãã°ããç°¡åã«èªã£ãŠããŸãã ãããè¡ãããã«ã圌ã¯
ãã¶ã€ã³ãã¿ãŒã³ãšã«ããŽãªçè«ã®é¢ä¿ã«é¢ããäžé£ã®èšäºãæžãå§ããŸããã 15åã®ç©ºãæéãããOOPshnikã¯ãæ©èœã ãã§ãªããé©åãªãªããžã§ã¯ãæåã®èšèšã«é¢ããæ ¹æ¬çã«æ°ããã¢ã€ãã¢ãšæŽå¯ã®ã»ãããæã«å
¥ããããšãã§ããŸãã 決å®çãªèŠå ã¯ã
ãã¹ãŠã®äŸãå®éã®CïŒãFïŒãããã³Haskellã³ãŒãã§ããããšã§ãã
ãã®ããã©ãã¹ãã¯ãã¢ãã€ãã«é¢ããäžé£ã®èšäºã®2çªç®ã®èšäºã§ãã
å§ããåã«ãèšäºã®ã¿ã€ãã«ã«ã€ããŠå°ã話ãããããšæããŸãã 2003幎ãKent Beckã®èæžã
Extreme ProgrammingïŒDevelopment through Testing㯠ãå
ã
äŸãšããŠTest-Driven DevelopmentãšåŒã°ããŠããŸãããããã§ã«ãã¹ãã»ã©ãŒã«ãªã£ãŠããŸãã ãã®ãããªãäŸãã®1ã€ã¯ããéã®äŸãã§ãããããã¯ã10ãã«ã10ãã©ã³ã®è¿œå ãªã©ãå€é貚æäœãå®è¡ã§ããã¢ããªã±ãŒã·ã§ã³ãäœæããã³ãªãã¡ã¯ã¿ãªã³ã°ããäŸã§ãã ãã®èšäºã®ã¿ã€ãã«ã¯ãã®æ¬ãžã®åç
§ã§ãããèšäºã®å
容ãããããç解ããããã«ããã®æåã®éšåãããç解ããããšã匷ããå§ãããŸãã
ããéã®äŸãKent Beckã«ã¯èå³æ·±ãç¹æ§ãããã€ããããŸããèŠããã«ãã¢ãã€ãã¯ãäžç«çãªèŠçŽ ïŒ
ãŠããã£ãšãåŒã°ããããšãããïŒãæã€é£æ³ãã€ããªæäœã§ãã
圌ã®æ¬ã®æåã®éšåã§ãKent Beckã¯ããã¹ãã«ããéçºãã®ååã䜿çšããŠãã·ã³ãã«ã§æè»ãªããããŒAPIããäœæããå¯èœæ§ãæ¢ããŸãã ãã®çµæã圌ã¯è§£æ±ºçãåŸãŸãããããã®èšèšã«ã¯ããã«æã®èŸŒãã äœæ¥ãå¿
èŠã§ãã
ã±ã³ãããã¯API
ãã®èšäºã§ã¯ã
Jawar Aminã«ãã£ãŠ
CïŒ ïŒå
ã®ã³ãŒãã¯Javaã§äœæãããïŒã«ç¿»èš³ãããKent Beckã®æ¬ã®ã³ãŒãã䜿çšããŸãã
ã±ã³ãã»ããã¯ã¯æ¬ã®äžã§ãã5 USD + 10 CHFããªã©ã®è¡šçŸãæ±ãããšãã§ãããããã€ãã®é貚ã§ãéãåŠçã§ãããªããžã§ã¯ãæåAPIãéçºããŠããŸããã æåã®ããŒãã®çµããã«åãã£ãŠã圌ã¯ïŒCïŒã«ç¿»èš³ãããïŒæ¬¡ã®ãããªã€ã³ã¿ãŒãã§ãŒã¹ãäœæããŸãã
public interface IExpression { Money Reduce(Bank bank, string to); IExpression Plus(IExpression addend); IExpression Times(int multiplier); }
Reduce
ã¡ãœããã¯ã
IExpression
ãªããžã§ã¯ãã
Money
ãªããžã§ã¯ããšããŠè¡šãããç¹å®ã®é貚ïŒ
to
ãã©ã¡ãŒã¿ãŒïŒã«å€æããŸãã ããã¯ãè€æ°ã®é貚ãå«ãåŒãããå Žåã«äŸ¿å©ã§ãã
Plus
ã¡ãœããã¯ã
IExpression
ãªããžã§ã¯ããçŸåšã®
IExpression
ãªããžã§ã¯ãã«è¿œå ããæ°ãã
IExpression
ãè¿ããŸãã 1ã€ã®é貚ãŸãã¯è€æ°ã®é貚ã§ãéãæ¯æãããšãã§ããŸãã
Times
ã¡ãœããã¯ã
IExpression
ã«ç¹å®ã®ä¿æ°ãä¹ç®ããŸãã ããããããã¹ãŠã®äŸã§ãå åãšåèšã«æŽæ°ã䜿çšããŠããããšã«æ°ã¥ããã§ãããã Kent Beckã¯ã³ãŒããè€éã«ããªãããã«ãããè¡ã£ããšæããŸãããå®éã«ã¯ãéãæ±ããšãã¯
decimal
ïŒããšãã°
decimal
ïŒã䜿çšããŸãã
è¡šçŸã®æ¯phor
㯠ããéãæ±ãããšãæ°åŒãæ±ãããšãšããŠã·ãã¥ã¬ãŒãã§ããããšã§ãã åçŽãªåŒã¯
5 USDã®ããã«èŠããŸããã
5 USD + 10 CHFãŸãã¯
5 USD + 10 CHF + 10 USDã®å ŽåããããŸãã
5 CHF + 7 CHFãªã©ã®ç°¡åãªåŒã¯ç°¡åã«
åæžã§ããŸãããçºæ¿ã¬ãŒãããªãå Žåã¯åŒ
5 USD + 10 CHFãèšç®ã§ããŸããã ãéã®ãã©ã³ã¶ã¯ã·ã§ã³ãããã«èšç®ããããšãã代ããã«ããã®ãããžã§ã¯ãã§ã¯åŒããªãŒãäœæããŠããããããå€æããŸãã ããªãã¿ã§ããã
Kent Beckã¯ã圌ã®äŸã§ã¯ã2ã€ã®ã¯ã©ã¹ã§
IExpression
ã€ã³ã¿ãŒãã§ã€ã¹
IExpression
å®è£
ã
IExpression
ãŸãã
Money
ã¯ãç¹å®ã®é貚ã§ã®äžå®ã®éé¡ã§ãã ãéé¡ãïŒæ°éïŒããã³ãé貚ãïŒé貚åïŒããããã£ãå«ãŸããŠããŸãã ãããéèŠãªãã€ã³ãã§ãã Money
ã¯äŸ¡å€ãªããžã§ã¯ãã§ããSum
ã¯ãä»ã®2ã€ã®IExpression
ãªããžã§ã¯ãã®åèšã§ãã ããã«ã¯ã Augend ïŒæåã®çšèªïŒãšAddend ïŒ2çªç®ã®çšèªïŒãšåŒã°ãã2ã€ã®çšèªãå«ãŸããŠããŸãã
åŒ
5 USD + 10 CHFãèšè¿°ããå Žåã次ã®ããã«ãªããŸãã
IExpression sum = new Sum(Money.Dollar(5), Money.Franc(10));
Money.Dollar
ãš
Money.Franc
ã¯ã
Money
ãªããžã§ã¯ããè¿ã2ã€ã®éçãã¡ã¯ããªã¡ãœããã§ãã
é£æ³æ§
Plus
ã¯ãã€ããªæŒç®ã§ããããšã«æ°ã¥ããŸãããïŒ åœŒå¥³ãã¢ãã€ããšèŠãªããŠãããã§ããïŒ
ã¢ãã€ãã«ãªãã«ã¯ãã¢ãã€ãã®
æ³åãæºãããªããã°ãªããŸããã
ã¢ãã€ãã®æåã®
æ³åã§ã¯ ãæäœã¯é£æ³çã§ãªããã°ãªããŸããã ã€ãŸãã3ã€ã®
IExpression
ãªããžã§ã¯ãã
x
ã
y
ãããã³
z
ã«ã€ããŠãåŒ
x.Plus(y).Plus(z)
ã¯
x.Plus(y.Plus(z))
ãšçãããªããã°ãªããŸããã ããã§å¹³çãã©ã®ããã«ç解ãã¹ãã§ããïŒ
Plus
ã¡ãœããã®æ»ãå€ã¯
IExpression
ã€ã³ã¿ãŒãã§ã€ã¹ã§ãããã€ã³ã¿ãŒãã§ã€ã¹ã«ã¯åçã®æŠå¿µã¯ãããŸããã ãã®ãããåçæ§ã¯ç¹å®ã®å®è£
ïŒ
Money
ããã³
Sum
ïŒã«äŸåããé©åãªã¡ãœããã決å®ãããã
ãã¹ãå¯Ÿå¿ ïŒãã¹ããã¿ãŒã³ã
ãã¹ãåºæã®åçæ§ -
çŽPerã ïŒã䜿çšã§ããŸãã
xUnit.netãã¹ã
ã©ã€ãã©ãªã¯ãã«ã¹ã¿ã ã³ã³ãã¬ãŒã¿ãŒã®å®è£
ãéããŠãã¹ãã³ã³ãã©ã€ã¢ã³ã¹ããµããŒãããŸãïŒãŠããããã¹ãæ©èœã®è©³çŽ°ãªç 究ã®ããã«ãèè
ã¯Pluralsight.comã§
é«åºŠãªãŠããããã¹ãã³ãŒã¹ãåè¬ããããšããå§ãããŸãïŒã ãã ããå
ã®Money APIã«ã¯æ¢ã«
IExpression
åã®ãªããžã§ã¯ããæ¯èŒããæ©èœããããŸãïŒ
Reduce
ã¡ãœããã¯ãä»»æã®
IExpression
ã
Money
åã®ãªããžã§ã¯ãïŒã€ãŸããåäžã®é貚ïŒã«å€æã§ããŸãããŸãã
Money
ã¯ãªããžã§ã¯ãå€ã§ããããã
æ§é çã«åçã§ã ïŒå€ãªããžã§ã¯ããšãã®æ©èœã®è©³çŽ°ã«ã€ããŠã¯ã
ãã¡ããåç
§ããŠãã ãã ïŒã ãããŠããã®ããããã£ã䜿çšããŠ
IExpression
ãªããžã§ã¯ããæ¯èŒã§ããŸãã å¿
èŠãªã®ã¯çºæ¿ã¬ãŒãã ãã§ãã
ã±ã³ãã»ããã¯ã¯æ¬ã®äžã§CHFãšUSDã®éã®2ïŒ1çºæ¿ã¬ãŒãã䜿çšããŠããŸãã ãã®èšäºã®å·çæç¹ã§ã¯ãçºæ¿ã¬ãŒãã¯0.96ã¹ã€ã¹ãã©ã³/ãã«ã§ãããããµã³ãã«ã³ãŒãã§ã¯ãã¹ãŠã®é貚ååŒã§æŽæ°ã䜿çšããŠãããããã¬ãŒãã1ïŒ1ã«äžžããå¿
èŠããããŸãã ãã ããããã¯ããªã銬鹿ããäŸãªã®ã§ã代ããã«å
ã®2ïŒ1çºæ¿ã¬ãŒãã«åºå·ããŸãã
次ã«ã
Reduce
ãšxUnit.netã®éã®
ã¢ããã¿ãŒã
IEqualityComparer<IExpression>
ã¯ã©ã¹ãšããŠèšè¿°ããŸãããã
public class ExpressionEqualityComparer : IEqualityComparer<IExpression> { private readonly Bank bank; public ExpressionEqualityComparer() { bank = new Bank(); bank.AddRate("CHF", "USD", 2); } public bool Equals(IExpression x, IExpression y) { var xm = bank.Reduce(x, "USD"); var ym = bank.Reduce(y, "USD"); return object.Equals(xm, ym); } public int GetHashCode(IExpression obj) { return bank.Reduce(obj, "USD").GetHashCode(); } }
ã³ã³ãã¬ãŒã¿ã2ïŒ1ã®çºæ¿ã¬ãŒãã§
Bank
ãªããžã§ã¯ãã䜿çšããŠããããšã«æ°ä»ããŸããã
Bank
ã¯ã©ã¹ã¯ãKent Beckã³ãŒãã®å¥ã®ãªããžã§ã¯ãã§ãã ããèªäœã¯ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããŸãããã
Reduce
ã¡ãœããã®åŒæ°ãšããŠäœ¿çšãããŸãã
ãã¹ãã³ãŒããèªã¿ãããããããã«ãè£å©çãªéçã¯ã©ã¹ãè¿œå ããŸãã
public static class Compare { public static ExpressionEqualityComparer UsingBank = new ExpressionEqualityComparer(); }
ããã«ãããçµåæäœã®ç䟡æ§ããã§ãã¯ããã¢ãµãŒããèšè¿°ã§ããŸãã
Assert.Equal( x.Plus(y).Plus(z), x.Plus(y.Plus(z)), Compare.UsingBank);
Java Aminã³ãŒãã®ãã©ãŒã¯ã§ããã®ã¢ãµãŒããFsCheckãã¹ãã«è¿œå ããŸãããããã¯ãFsCheckãçæãããã¹ãŠã®
Sum
ããã³
Money
ãªããžã§ã¯ãã«äœ¿çšãããŸãã
çŸåšã®å®è£
ã§ã¯ã
IExpression.Plus
é£æ³ã§ããããã®åäœãä¿èšŒãããŠããªãããšã«æ³šæãã䟡å€ããããŸããçç±ã¯æ¬¡ã®ãšããã§ã
IExpression
ã¯ã€ã³ã¿ãŒãã§ã€ã¹ã§ãããããçµåæ§ã«éåãã3çªç®ã®å®è£
ãç°¡åã«è¿œå ã§ããŸãã æ¡ä»¶ä»ãã§ã
Plus
æäœã¯çµåçã§ãããšæ³å®ããŸãããç¶æ³ã¯åŸ®åŠã§ãã
äžç«èŠçŽ
IExpression.Plus
çµåçã§ããããšã«åæããå Žåãããã¯ã¢ãã€ãã®åè£ã§ãã äžç«çãªèŠçŽ ãããå Žåãããã¯ééããªãã¢ãã€ãã§ãã
ã±ã³ãããã¯ã¯äŸã«äžç«çãªèŠçŽ ãè¿œå ããªãã£ãã®ã§ãèªåã§è¿œå ããŸãã
public static class Plus { public readonly static IExpression Identity = new PlusIdentity(); private class PlusIdentity : IExpression { public IExpression Plus(IExpression addend) { return addend; } public Money Reduce(Bank bank, string to) { return new Money(0, to); } public IExpression Times(int multiplier) { return this; } } }
ååšã§ããäžç«èŠçŽ ã¯1ã€ã ããªã®ã§ãããã
ã·ã³ã°ã«ãã³ã«ããããšã¯çã«ããªã£ãŠããŸãã ãã©ã€ããŒãã¯ã©ã¹
PlusIdentity
ã¯ãäœãããªã
IExpression
æ°ããå®è£
ã§ãã
Plus
ã¡ãœããã¯ãåã«å
¥åå€ãè¿ããŸãã ããã¯ãæ°åãè¿œå ããã®ãšåãåäœã§ãã è¿œå ããããšããŒãã¯äžç«çãªèŠçŽ ã§ãããããã§ãåãããšãèµ·ãããŸãã ããã¯ã
Reduce
ã¡ãœããã§ããæ確ã«èŠãããŸã
Reduce
ã¡ãœããã§ã¯ããäžç«ãé貚ã®èšç®ã¯ãèŠæ±ãããé貚ã§ãŒãã«åçŽã«åæžãããŸãã æåŸã«ãäžç«èŠçŽ ã«äœããæãããšãäžç«èŠçŽ ãåŸãããŸãã ããã§èå³æ·±ãããšã«ã
PlusIdentity
ã¯ä¹ç®æŒç®ã®ãã¥ãŒãã©ã«èŠçŽ ãšåæ§ã«åäœããŸãïŒ1ïŒã
ããã§ã
IExpression
x
ãã¹ããäœæããŸãã
Assert.Equal(x, x.Plus(Plus.Identity), Compare.UsingBank); Assert.Equal(x, Plus.Identity.Plus(x), Compare.UsingBank);
ããã¯ããããã£ãã¹ãã§ãããFsCheckã«ãã£ãŠçæããããã¹ãŠã®
x
å®è¡ãããŸãã
Plus.Identity
é©çšããã泚æã¯ããã«ãé©çšãããŸãïŒ
IExpression
ã¯ã€ã³ã¿ãŒãã§ã€ã¹ã§ããããã
Plus.Identity
ã誰ããäœæã§ãããã¹ãŠã®
IExpression
å®è£
ã«å¯ŸããŠäžç«çãªèŠçŽ ã«ãªããã©ããã¯
Plus.Identity
ãŸãããã3ã€ã®æ¢åã®å®è£
ã«ã€ããŠã¯ãã¢ãã€ãã®æ³åãä¿æãããŸãã
ããã§ãæäœ
IExpression.Plus
ã¯ã¢ãã€ãã§ãããšèšããŸãã
ä¹ç®
ç®è¡ã§ã¯ãä¹ç®æŒç®åã¯ãåããšåŒã°ããŸãïŒè±èªã§ã¯ãåã-
çŽPerã ïŒã
3 * 5ãšæžããšãæåéã
3
5åïŒãŸãã¯
5
3åïŒïŒããããšãæå³ããŸãã èšãæããã°ïŒ
3 * 5 = 3 + 3 + 3 + 3 + 3
IExpression
åæ§ã®æäœããããŸããïŒ
ãããããã¢ãã€ããšã»ãã°ã«ãŒããã¡ã€ã³ã©ã€ãã©ãªã®äžéšã§ããHaskellèšèªã§ãã³ããèŠã€ããããšãã§ããŸãã åŸã§ã»ãã°ã«ãŒãã«ã€ããŠåŠç¿ããŸãããä»ã®ãšããã
Semigroup
ã¯ã©ã¹ã
Semigroup
stimes
é¢æ°ãå®çŸ©ããŠããããšã«æ³šæããŠãã ããããã®é¢æ°ã¯
Integral b => b -> a -> a
stimes
Integral b => b -> a -> a
åã§ãã ã€ãŸããæŽæ°åïŒ16ãããæŽæ°ã32ãããæŽæ°ãªã©ïŒã®å Žåã
stimes
é¢æ°ã¯æŽæ°ãåãåããaã®å€ãšãã®å€ã«æ°å€ãä¹ç®ããŸãã ããã§
a
ã¯äºé
æŒç®ãååšããåã§ãã
CïŒã§ã¯ã
stimes
é¢æ°ã¯
Foo
ã¯ã©ã¹ã®ã¡ãœããã®ããã«ãªããŸãã
public Foo Times(int multiplier)
åå
stimes
æå
s
ã
stimes
æå³ãã
s
ã§ã¯ãªã
STimes
ãšåŒ·ãçãã®ã§ã
STimes
ã§ã¯ãªã
Times
ã¡ãœããã
Semigroup
ã ãŸãããã®ã¡ãœããã«ã¯
IExpression.Times
ã¡ãœãããšåãã·ã°ããã£ãããããšã«æ³šæããŠ
IExpression.Times
ã
Haskellã§ãã®ãããªé¢æ°ã®æ®éçãªå®è£
ãå®çŸ©ã§ããå ŽåãCïŒã§åãããšãè¡ãããšã¯å¯èœã§ããïŒ
Money
ã¯ã©ã¹ã§ã¯ã
Plus
ã¡ãœããã䜿çšããŠ
Times
ãå®è£
ã§ããŸãã
public IExpression Times(int multiplier) { return Enumerable .Repeat((IExpression)this, multiplier) .Aggregate((x, y) => x.Plus(y)); }
LINQã©ã€ãã©ãªã®
Repeat
éçã¡ãœããã¯ã
multiplier
æå®ãããåæ°ã ã
this
ãè¿ããŸãã æ»ãå€ã¯
Enumerable<IExpression>
ã§ããã
IExpression
ã€ã³ã¿ãŒãã§ã€ã¹ã«åŸã£ãŠ
IExpression
Times
ã¯åäžã®
IExpression
å€ãè¿ãå¿
èŠããããŸãã
Aggregate
ã¡ãœããã䜿çšããŠã
Plus
ã¡ãœããã䜿çšããŠ2ã€ã®
IExpression
å€ïŒ
x
ããã³
y
ïŒã1ã€ã«ç¹°ãè¿ãçµåããŸãã
ãã®å®è£
ã¯ã以åã®ç¹å®ã®å®è£
ã»ã©å¹æçã§ã¯ãããŸããããããã§ã¯å¹çã«ã€ããŠã§ã¯ãªããäžè¬çãªåå©çšãããæœè±¡åã«ã€ããŠèª¬æããŸãã ãŸã£ããåãå®è£
ã
Sum.Times
ã¡ãœããã«äœ¿çšã§ããŸãã
public IExpression Times(int multiplier) { return Enumerable .Repeat((IExpression)this, multiplier) .Aggregate((x, y) => x.Plus(y)); }
ããã¯
Money.Times
ãšãŸã£ããåãã³ãŒã
Money.Times
ã ãã®ã³ãŒãã
PlusIdentity.Times
ã«ã³ããŒããŠè²Œãä»ããããšãã§ããŸãããäžèšãšåãã³ãŒããªã®ã§ãããã§ã¯ç¹°ãè¿ããŸããã
ããã¯ã
IExpression
ãã
Times
ã¡ãœãããåé€ã§ããããšãæå³ããŸãã
public interface IExpression { Money Reduce(Bank bank, string to); IExpression Plus(IExpression addend); }
代ããã«ã
æ¡åŒµã¡ãœãããšããŠå®è£
ããŸãïŒ
public static class Expression { public static IExpression Times(this IExpression exp, int multiplier) { return Enumerable .Repeat(exp, multiplier) .Aggregate((x, y) => x.Plus(y)); } }
IExpression
ãªããžã§ã¯ãã«ã¯
Plus
ã¡ãœããããããããããã¯æ©èœããŸãã
å
ã»ã©èšã£ãããã«ãããã¯å°éçãª
Times
å®è£
ãããå¹æãäœãå¯èœæ§ããããŸãã Haskellã§ã¯ãéçºè
ãããã©ã«ãã®å®è£
ãããå¹ççãªã¢ã«ãŽãªãºã ãå®è£
ã§ããããã«ã
ã¿ã€ãã¯ã©ã¹ã«stimesãå«ããããšã§ãããæé€ããŠããŸãã CïŒã§ã¯ã
Times
ããããªãã¯ä»®æ³ïŒãªãŒããŒã©ã€ãå¯èœïŒã¡ãœãããšããŠäœ¿çšããŠã
IExpression
ãæœè±¡åºæ¬ã¯ã©ã¹ã«åç·šæããããšã«ãããåãå¹æãå®çŸã§ããŸãã
æ€èšŒãã§ãã¯
Haskellèšèªã«ã¯ã¢ãã€ãã®ããæ£åŒãªå®çŸ©ããããããåã«ã¢ã€ãã¢ã®èšŒæ ãšããŠHaskellã§Kent Beck APIãæžãæããããšãã§ããŸãã ç§ã®æåŸã®å€æŽã§ã¯ãCïŒã®ãã©ãŒã¯ã«ã¯
IExpression
3ã€ã®å®è£
ããããŸãã
ã€ã³ã¿ãŒãã§ã€ã¹ã¯æ¡åŒµå¯èœã§ããããããããåŠçããå¿
èŠããããŸãããããã£ãŠãHaskellã§ã¯ãããã3ã€ã®ãµãã¿ã€ããã¿ã€ã
sum
ãšããŠå®è£
ããæ¹ãå®å
šã ãšæãããŸãã
data Expression = Money { amount :: Int, currency :: String } | Sum { augend :: Expression, addend :: Expression } | MoneyIdentity deriving (Show)
ããæ£åŒã«ã¯ã
Monoid
ã䜿çšããŠãããè¡ãããšãã§ããŸã
Monoid
instance Monoid Expression where mempty = MoneyIdentity mappend MoneyIdentity y = y mappend x MoneyIdentity = x mappend xy = Sum xy
CïŒã®äŸã®
Plus
ã¡ãœããã¯ã
mappend
é¢æ°ã§è¡šãããŠ
mappend
ãŸãã
IExpression
ã¯ã©ã¹ã®æ®ãã®ã¡ã³ããŒã¯ã
Reduce
ã¡ãœããã®ã¿ã§ããããã¯ã次ã®ããã«å®è£
ã§ããŸãã
import Data.Map.Strict (Map, (!)) reduce :: Ord a => Map (String, a) Int -> a -> Expression -> Int reduce bank to (Money amt cur) = amt `div` rate where rate = bank ! (cur, to) reduce bank to (Sum xy) = reduce bank to x + reduce bank to y reduce _ _ MoneyIdentity = 0
ãã以å€ã¯ãã¹ãŠtypclassã¡ã«ããºã ã«ãã£ãŠåŠçãããããã次ã®ããã«Kent Beckã®ãã¹ãã®1ã€ãåçŸã§ããŸãã
λ> let bank = fromList [(("CHF","USD"),2), (("USD", "USD"),1)] λ> let sum = stimesMonoid 2 $ MoneyPort.Sum (Money 5 "USD") (Money 10 "CHF") λ> reduce bank "USD" sum 20
stimesMonoid
ãã¹ãŠã®
Semigroup
ã§æ©èœããããã«ã
stimesMonoid
ãã¹ãŠã®
Semigroup
ã§å®çŸ©ãããŠããããã
Expression
ã§ã䜿çšã§ããŸãã
éå»ã®çºæ¿ã¬ãŒãã2ïŒ1ã®å Žåãã5ãã«+ 10ã¹ã€ã¹ãã©ã³Ã2ãã¯æ£ç¢ºã«20ãã«ã«ãªããŸãã
ãŸãšã
圌ã®æ¬ã®ç¬¬17ç« ã§ã¯ãKent BeckãMoney APIã®ããŸããŸãªããªãšãŒã·ã§ã³ããè¡šçŸäžãã«ããããšããåã«ç¹°ãè¿ãèæ¡ããããšããæ¹æ³ã説æããæçµçã«æ¬ã§äœ¿çšããŸããã èšãæããã°ã圌ã¯ãã®ç¹å®ã®åé¡ãšäžè¬çãªããã°ã©ãã³ã°ã®äž¡æ¹ã§å€ãã®çµéšãæã£ãŠããŸããã æããã«ããã®äœæ¥ã¯é«åºŠãªè³æ Œãæã€ããã°ã©ããŒã«ãã£ãŠè¡ãããŸããã
ãããŠã圌ãçŽæçã«ãã¢ãã€ããã¶ã€ã³ãã«æ¥ãŠããããã«æããã®ã¯äžæè°ã«æããŸããã ãããã圌ã¯æå³çã«ãããè¡ã£ãã®ã§ïŒæ¬ã§ããã«ã€ããŠã¯èª¬æããŠããŸããïŒããã®åªäœæ§ã«æ°ä»ãããšããçç±ã ãã§ãã®ãã¶ã€ã³ã«æ¥ããšæããŸãã ã¢ãã€ãããŒã¹ã®APIã«é¢ããŠéåžžã«ç解ãããããã®ããããšããèããäžããããã
ãã®äŸãã¢ãã€ããšããŠ
å
·äœçã«æ€èšããããšã¯ç§ã«ãšã£ãŠèå³æ·±ãããã§ãã æŠå¿µçã«ã¯ãããã¯åã«ãå°ããªè¿œå ãã§ãã
ãã®èšäºã§ã¯ã9幎åã®ã³ãŒãïŒå®éã«ã¯15æ³
-çŽLane ïŒã«æ»ããã¢ãã€ããšããŠèå¥ããŸããã 次åã®èšäºã§ã¯ã2015幎ã®ã³ãŒããä¿®æ£ããŸãã
ãããã«
ããã§ãã®èšäºã¯çµããã§ãã ããã¯ãªã³ã¯ã§ãªã³ã¯ãããHabréãžã®é£ç¶ããæçš¿ãšãã圢ã§ããªãªãžãã«ãšåãæ¹æ³ã§å
¬éãããæ
å ±ããŸã ãããããããŸãã 以äžïŒå
ã®èšäºã¯
Mark Seemann 2017ã§ããã翻蚳ã¯Javaã³ãã¥ããã£ã«ãã£ãŠè¡ããã翻蚳è
ã¯Evgeny Fedorovã§ãã