å®éã«OOPã䜿çšããå Žåã¯ã ããã¶ã€ã³ãã¿ãŒã³ããªã©ã«ç²ŸéããŠããŸãã ãã®æšæºãªã¹ãã«åãŸããªã䟿å©ãªãã¿ãŒã³ãããããããããšããåç¥ã§ããïŒ æ®å¿µãªããããããã®å€ãã¯ãé¢æ°åããã°ã©ãã³ã°ãã«é¢é£ä»ããããŠãããäŒèª¬ã«ãããšãããã¯è€éã§é£è§£ã§ãã ãã¢ãã€ãããšããèšèã10åèšããšãæªéãåŒã¶ããšãã§ããŸãã
Mark Seemanãé¢æ°åããã°ã©ãã³ã°ã«ã€ããŠãã°ããç°¡åã«èªã£ãŠããŸãã ãããè¡ãããã«ã圌ã¯ãã¶ã€ã³ãã¿ãŒã³ãšã«ããŽãªçè«ã®é¢ä¿ã«é¢ããäžé£ã®èšäºãæžãå§ããŸããã 15åã®ç©ºãæéãããOOPshnikã¯ãæ©èœã ãã§ãªããé©åãªãªããžã§ã¯ãæåã®èšèšã«é¢ããæ ¹æ¬çã«æ°ããã¢ã€ãã¢ãšæŽå¯ã®ã»ãããæã«å
¥ããããšãã§ããŸãã 決å®çãªèŠå ã¯ã ãã¹ãŠã®äŸãå®éã®CïŒãFïŒãããã³Haskellã³ãŒãã§ããããšã§ãã ãã®habrapostã¯ããµã€ã¯ã«ã®æåã®éšåã翻蚳ãããã®ã§ãæåã®3ã€ã®èšäºã¯ç解ããããããã«ãŸãšããããŠããŸãã
ããã«ã2017幎11æ12ã13æ¥ã«ã¢ã¹ã¯ã¯ã®ã¹ã©ãã£ã³ã¹ã¯ã©ãã£ãœã³ã§ éå¬ãããDotNext 2017 Moscowã«ã³ãã¡ã¬ã³ã¹ã«åå ããŠãMarkãšã©ã€ãã§ãã£ããã§ããŸãã ããŒã¯ã¯ãäŸåæ§æ³šå
¥ããäŸåæ§æåŠãŸã§ãã«é¢ããè¬æŒãèªã¿ãŸãã ãã±ããã¯ãã¡ãã§å
¥æã§ããŸã ã
ãã®ããã¹ãã¯ãã¶ã€ã³ãã¿ãŒã³ãšã«ããŽãªãŒçè«ã®éã®ãªã³ã¯ã«é¢ããæ°ããã·ãªãŒãºã®äžéšã§ãã
é¢æ°åããã°ã©ãã³ã°ã¯éåžžããã®ç¹æ®ãªå°éçšèªã§æ¹å€ãããŸãã æ¥åäœå圢æ
åçãªã©ã®çšèªã¯ãåå¿è
ã«æ¬è³ªãäŒããã®ã«åœ¹ç«ã¡ãŸããã ããããç³ãæããåã«ããŸãèªåã®ã¬ã©ã¹ã®å®¶ãåºãªããã°ãªããŸããã ãªããžã§ã¯ãæåèšèšã§ã¯ã Bridge ã Visitor ã SOLID ã æ¥ç¶æ§ãªã©ã®ååã䜿çšãããŸãã èšèã¯ããªãã¿ã®ããã«èãããŸãããã³ãŒãã§èšªåè
ãã¿ãŒã³ã説æãŸãã¯å®è£
ãããããæ¥ç¶æ§ããšã¯äœãã説æãããã§ããŸããïŒ
ããªããžãšããèšèèªäœã¯ããªããžã§ã¯ãæåã®çšèªãæ¹åãããã®ã§ã¯ãããŸããã ããããããã¯åœŒå¥³ãããã«æªåãããŸãã æçµçã«ããã®èšèã¯ãããŸãã«ãªããŸããã2ã€ã®ç°ãªãå Žæãçµã¿åãããå®éã®ç©çãªããžã§ã¯ããæå³ããã®ã§ããããããããšããã¶ã€ã³ãã¿ãŒã³ã«ã€ããŠè©±ããŠããã®ã§ããããã ãã¡ãããå®éã«ã¯ãã³ã³ããã¹ããããããç解ããŸãããããã¯äºå®ããã£ã³ã»ã«ããŸãã-誰ããæ©ã®ãã¿ãŒã³ã«ã€ããŠè©±ãå Žåãäºåã«ãããåŠãã§ããªãå Žåãããªãã¯å
šãäœãç解ããŸããã åèªãããªãã¿ã®ããã«èããããããšãã£ãŠãããã䟿å©ã«ãªãããã§ã¯ãããŸããã
å€ãã®ãªããžã§ã¯ãæåããã°ã©ããŒã¯ããåŒæ°ãšããŠåãåã£ããã®ãšåãåãè¿ãæäœãã®æçšæ§ãçºèŠããŸããã ããã«ããããããããã®ãããªèšè¿°ããã®ãããªèŸæžã¯éåžžã«äžäŸ¿ã§ãã ãã®æäœãäžèšã§èª¬æããæ¹ãè¯ããšæããŸãããïŒ ã¢ãã€ãã§ããã ã»ãã°ã«ãŒãã§ããïŒ
ãªããžã§ã¯ãæåã®æŽå¯
ãã¡ã€ã³é§åèšèšã®æ¬ã§ã Eric Evansã¯Closure of Operationsã®æŠå¿µã«ã€ããŠèªã£ãŠããŸãã ååã瀺ãããã«ãããã¯ãæ»ãå€ã®åãåŒæ°ã®åãšäžèŽããæäœãã§ãã CïŒã§ã¯ã眲åpublic Foo Bar(Foo f1, Foo f2)
æã€ã¡ãœããã§ããå¯èœæ§ããããŸãã ãã®ã¡ãœããã¯ã2ã€ã®Foo
ãªããžã§ã¯ããå
¥åãšããŠåãåãã Foo
ãªããžã§ã¯ããè¿ããŸãã
ãšãŽã¡ã³ã¹ãææããããã«ããã®ããã«èšèšããããªããžã§ã¯ãã¯ããŸãã§ç®è¡ã圢æããŠããããã«èŠãå§ããŸãã Foo
ãåãå
¥ããŠFoo
ãè¿ãæäœãããå Žåãããã¯äœã§ããããïŒ ãã¶ãè¿œå ïŒ ä¹ç®ïŒ ä»ã®æ°åŠæŒç®ã¯ãããŸããïŒ
äžéšã®ãšã³ã¿ãŒãã©ã€ãºéçºè
ã¯ãåã«ãããžãã¹ãããŠå
ã«é²ã¿ãããã ãã§ãæ°åŠã«ãŸã£ããæ©ãŸãããŠããŸããã 圌ãã«ãšã£ãŠãã³ãŒãããããæ°åŠçãªããã®ã«ãããšããèãã¯éåžžã«ç©è°ãããããŸãã ããã«ããããããããæ°åŠã奜ãã§ã¯ãªããå Žåã§ããå ç®ãä¹ç®ãªã©ã®æå³ã確å®ã«ç解ã§ããŸãã ãã¹ãŠã®ããã°ã©ããŒãç解ããŠããããã«ãç®è¡ã¯åŒ·åãªé phorã§ãã
圌ã®æåãªæ¬ã Test-Driven DevelopmentïŒExample byãã§ã¯ã Kent Beckã¯åãèããå©çšããããã§ãã ç§ã¯åœŒãã©ããã§ããã«ã€ããŠçŽæ¥æžãããšã¯æããªããã
ãšãŽã¡ã³ã¹ãæžããã®ã¯ãã¢ãã€ããã»ãã°ã«ãŒããããã³æœè±¡ä»£æ°ããã®åæ§ã®æŠå¿µã§ãã å
¬å¹³ãæããŠãæè¿åœŒãšè©±ãããŸããããä»ã§ã¯åœŒã¯ããããã¹ãŠã«ç²ŸéããŠããŸãã 圌ã¯DDDãæžããã2003幎ã«ããããç解ããŸããã-ç§ã¯ç¥ããŸããããç§ã¯ééããªãç解ããŸããã ããã§ã®ç§ã®ä»äºã¯ãæãçªãã®ã§ã¯ãªããéåžžã«è³¢ã人ã
ãOOPã§äœ¿çšã§ããååãéçºããããšã瀺ãããšã§ãã
ããã¯ãã¹ãŠã©ããã£ãŠã€ãªãã£ãŠããã®
ã¢ãã€ããšã»ãã°ã«ãŒãã¯ããã°ããšåŒã°ãããã倧ããªæäœã°ã«ãŒãã«å±ããŸãã ããã«ã€ããŠã¯åŸã§èª¬æããŸãããã¢ãã€ãããå§ããŠã»ãã°ã«ãŒãã«é²ã¿ããã°ãã«ç§»ããŸãã ãã¹ãŠã®ã¢ãã€ãã¯ã»ãã°ã«ãŒãã§ããããã®éã¯åœãŠã¯ãŸããŸããã ã€ãŸããã¢ãã€ãã¯ã»ãã°ã«ãŒãã®ãµãã»ããã圢æããŸãã

ãããã¯ã2ã€ã®Foo
å€ãå
¥åãšããŠåãåããåºåã§Foo
åã®å€ãè¿ãæäœã®åœ¢åŒã§ãã€ããªæäœãèšè¿°ããŸãã äž¡æ¹ã®ã«ããŽãªã¯ïŒçŽèŠ³çãªïŒæ³åŸã§èšè¿°ãããŠããŸãã éãã¯ãã¢ãã€ãã®æ³åãã»ãã°ã«ãŒãã®æ³åãããå³å¯ã§ããããšã§ãã çšèªã«åºå·ããªãã§ãã ããããæ³ããšããèšèã¯ãæ·±å»ãªè€éãªæ°åŠãé¢ä¿ããŠããããã«èããããããããŸãããããããã®ãæ³ãã¯ã·ã³ãã«ã§çŽæçã§ãã ãããã«ã€ããŠã¯ã次ã®éšåã§èª¬æããŸãïŒãã®ãã¡çŽ15åïŒã
ãããã¯ãã¹ãŠæ°åŠãšå¯æ¥ã«é¢é£ããŠãããšããäºå®ã«ããããããããšããããåªãããªããžã§ã¯ãæåèšèšã®ããã®å€ãã®ã¢ã€ãã¢ãæäŸããããã«èšèšãããŠããŸãã
ãŸãšã
éåžžã®ãªããžã§ã¯ãæåããã°ã©ããŒã®å Žåã ã¢ãã€ããã»ãã°ã«ãŒãã®ãããªçšèªã¯ã建ç¯ã®å®å®é£è¡å£«ãäœãæ°åŠãã¢ã«ãããŒã象çã®å¡ã®ãããªåããããŸãã ããããå®éã«ã¯ããããã¯ã·ã³ãã«ã§äŸ¿å©ãªã¢ã€ãã¢ã§ããã誰ãã誰ãããã«15åãè²»ããã®ãé¢åã§ã¯ãªãããç解ã§ããŸãã
çµè«ïŒOOPããã°ã©ããŒã®ããã®ã¢ãã€ãã®çŽ¹ä»ã
ãã®ã»ã¯ã·ã§ã³ã¯ãã¢ãã€ããã»ãã°ã«ãŒããããã³é¢é£ããæŠå¿µã«é¢ããäžé£ã®èšäºã®äžéšã§ãã ãã®ã»ã¯ã·ã§ã³ãåŠç¿ãããšãã¢ãã€ããšã¯äœããã»ãã°ã«ãŒããšã¯ã©ã®ããã«ç°ãªãããç解ã§ããŸãã

ã¢ãã€ãã¯ãã»ãã°ã«ãŒãã®ãµãã»ããã圢æããŸãã ã¢ãã€ããæ©èœããã«ãŒã«ã¯ãã»ãã°ã«ãŒããããå³å¯ã§ãã æåã«ã»ãã°ã«ãŒãã«å¯ŸåŠãããããã«åºã¥ããŠã¢ãã€ãã«é²ãæ¹ããããšå€æããããšãã§ããŸãã å³å¯ã«èšãã°ãéå±€ã®èŠ³ç¹ã§ã¯ãããã¯çã«ããªã£ãŠããŸãã ããããã¢ãã€ãã¯ã¯ããã«çŽæçã ãšæããŸãã ã¢ãã€ãã®æåã®äŸãèŠããšãããããæ¥åžžç掻ããã®ãã®ãèšè¿°ããŠããããšãããã«ããããŸãã ã¢ãã€ãã®äŸãèŠã€ããã®ã¯ç°¡åã§ãããã»ãã°ã«ãŒãã®è¯ãäŸãéžæããã«ã¯ãè©ŠããŠã¿ãå¿
èŠããããŸãã ãããã£ãŠãã¢ãã€ãããå§ããŸãã
ã¢ãã€ãæ³
å ç®ïŒ 40 + 2
ïŒãšä¹ç®ïŒ 6 * 7
ïŒã®å
±éç¹ã¯äœã§ããïŒ
ãããã®æäœã®äž¡æ¹
- é£æ³
- äºé
æŒç®ã§ã
- äžç«çãªèŠçŽ ãæã£ãŠãã
ã¢ãã€ãã圢æããããã«å¿
èŠãªã®ã¯ããã ãã§ãã äžç«çãªèŠçŽ ã®çµåæ§ãšååšã¯ããã¢ãã€ãæ³ããŸãã¯ãã¢ãã€ãæ³ãïŒè±èªã§ã¯ã¢ãã€ãæ³ ïŒãšåŒã°ããŸãã ã¢ãã€ãã¯ããŒã¿åãšæäœã®çµã¿åããã§ããããšã¯æ³šç®ã«å€ããŸãã ã€ãŸããåãªãåã§ã¯ãªãããã®åã§æ©èœããé¢æ°ïŒãŸãã¯ã¡ãœããïŒã§ãã ããšãã°ãå ç®ãšä¹ç®ã¯ãæ°å€ã«äœçšãã2ã€ã®ç°ãªãã¢ãã€ãã§ãã
ãã€ããª
æãåçŽãªãã®ããå§ããŸãããã 2ã€ã®å€ã§æ©èœããå Žåãæäœã¯ããã€ããªãã§ãã ãããããããã€ããªããšããèšèã«èšåãããšãäž»ã«101010ãªã©ã®ãã€ããªããŒã¿ã衚瀺ãããŸããããã®åèªã¯ã©ãã³èªã«ç±æ¥ãããã¢ãªãã£2ãã«é¢é£ãããã®ãæå³ããŸãã 倩æåŠè
ã¯æã
ãã€ããªã¹ã¿ãŒã«ã€ããŠã話ããŸãããçŸåšã§ã¯ãã®èšèã¯äž»ã«ã³ã³ãã¥ãŒã¿ã®æèã§äœ¿çšãããŠããŸãããã€ããªããŒã¿ã«å ããŠããããããã€ããªããªãŒã«ã€ããŠèããããšãããã§ãããã äºé
æŒç®ãšããã°ãäž¡æ¹ã®å
¥åå€ãåãåã§ãããæ»ãå€ã®åãå
¥ååãšäžèŽããããšãæå³ããŸãã èšãæããã°ãCïŒã§ã¯ããã®ãããªã¡ãœããã¯æå¹ãªãã€ããªæŒç®ã§ãã
public static Foo Op(Foo x, Foo y)
Op
ãFoo
ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã¡ãœããã§ããå Žåã次ã®ããã«ãªããŸãã
public Foo Op (Foo foo)
äžæ¹ãããã¯ãã¯ããã€ããªæäœã§ã¯ãããŸããã
public static Baz Op(Foo f, Bar b)
2ã€ã®å
¥ååŒæ°ãåããŸãããåã¯ç°ãªããæ»ãå€ã®åãç°ãªããŸãã
ãã¹ãŠã®åŒæ°ãšæ»ãå€ã¯åãåã§ããããããã€ããªæäœã¯Eric EvansãDomain-Driven Designã® Closure of OperationsãšåŒãã ãã®ã§ãã
é£æ³æ§
ã¢ãã€ãã®åœ¢æã®ããã«ãäºé
æŒç®ã¯å¿
ãé£æ³çã§ãªããã°ãªããŸããã ããã¯åã«ãèšç®ã®é åºãéèŠã§ãªãããšãæå³ããŸãã ããšãã°ãè¿œå ã®å Žåãããã¯æ¬¡ã®ããšãæå³ããŸãã
(2 + 3) + 4 = 2 + (3 + 4) = 2 + 3 + 4 = 9
ä¹ç®ã«ã€ããŠãåæ§ïŒ
(2 * 3) * 4 = 2 * (3 * 4) = 2 * 3 * 4 = 24
äžèšã®Op
ã¡ãœããã«ã€ããŠèª¬æããå Žåãçµåæ§ã§ã¯ã次ã®ã³ãŒãã«å¯ŸããŠareEqual
ãtrue
ã§ããå¿
èŠããããŸãã
var areEqual = foo1.Op(foo2).Op(foo3) == foo1.Op(foo2.Op(foo3));
å·ŠåŽã§ã¯ã foo1.Op(foo2)
èšç®ããã次ã«çµæãfoo3
ã«é©çšããfoo3
ã å³åŽã§ã¯ã foo2.Op(foo3)
æåã«èšç®ãããçµæã¯foo1.Op
åŒæ°ã«foo1.Op
å·ŠåŽãšå³åŽã¯==æŒç®åã䜿çšããŠæ¯èŒããããããçµåæ§ã§ã¯areEqual
ãtrue
å¿
èŠãããtrue
ã
ãã®æ§é å
šäœãCïŒã§æ©èœããããã«ã¯ãäœããã®èªäœã¢ãã€ãFoo
å Žåã Equals
ããªãŒããŒããŒããã ==
æŒç®åãå®è£
ããå¿
èŠããããŸãã
äžç«èŠçŽ
ã¢ãã€ãã®3çªç®ã®ã«ãŒã«ã¯ãäžç«çãªèŠçŽ ãååšããå¿
èŠããããšããããšã§ãã éåžžã ãŠããããšåŒã°ããŸãïŒæé©ãªååã§ã¯ãããŸããããããã°ããäžç«èŠçŽ ããããåªããŠããŸãïŒã å°æ¥çã«ã¯ãããåŒã³åºããŸãã
åäœã¯ããäœãããªããå€ã§ãã ããšãã°ãè¿œå ã®å Žåã¯0
ã§ã0
ãŒããè¿œå ããŠãå
ã®å€ãšã¯äœãå€ãããªããããå€æŽãããŸããã
0 + 42 = 42 + 0 = 42
ç°¡åãªæŒç¿ïŒä¹ç®ã®åäœãæšæž¬ããŸãã
äžèšã®åèšã®èšé²ã¯ããŠããããå·ŠåŽã§äœ¿çšãããå Žåãšå³åŽã§äœ¿çšãããå Žåã®äž¡æ¹ã§ããŠããããäžç«çã«åäœããå¿
èŠãããããšãæå³ããŸãã Foo
ãªããžã§ã¯ãã®å Žåãããã¯æ¬¡ã®ããã«èšè¿°ã§ããŸãã
var hasIdentity = Foo.Identity.Op(foo) == foo.Op(Foo.Identity) && foo.Op(Foo.Identity) == foo;
ããŒã«å€ãåŠçããã¢ãã€ããããã€ããããŸãïŒ allãšanyã§ãã ããªãã¯ã©ãæããŸããã圌ãã¯ã©ã®ããã«æ©èœããŸããïŒ åœŒãã®ãŠãããã¯äœã§ããïŒ
æŒç¿ãšããŠã any
ïŒããã³ããããã°ãŒã°ã«ã§ïŒãæ¯ãè¿ãããšãã§ããŸãã 次ã®ã»ã¯ã·ã§ã³ã§ã¯ãä»ã®ããèå³æ·±ãã¢ãã€ãã瀺ããŸãã ãã®ãããã¹ãã§ã¯ãè¡ããªã¹ããããã³ã·ãŒã±ã³ã¹ã®ã¿ãèæ
®ãããŸã-æ®ãã®èšäºã¯ãŸã å·çäžã§ãã
å®éããæ°å€ã®ããã«æ¯ãèããããŒã¿åãããå Žåãã»ãšãã©ã®å Žåãããããã¢ãã€ããäœæã§ããŸãã å ç®ã¯æãç°¡åãªåè£ã®1ã€ã§ãããªããªããæãç°¡åã«ç解ã§ãã枬å®åäœã®ãããªãã®ããããå¿
èŠããªãããã§ãã ããšãã°ã.NETåºæ¬ã¯ã©ã¹ã©ã€ãã©ãªã«ã¯ã Addã¡ãœãããæã€TimeSpanæ§é ããããŸãã æŒç®å==
圌女ãæã£ãŠããŸãã äžæ¹ã TimeSpan
ã«ã¯Multiply
ã¡ãœããããããŸããããªããªãã2ã€ã®æéãä¹ç®ããçµæã¯ã©ããªãã®ã§ããããïŒ ã¹ã¯ãšã¢ã¿ã€ã ïŒ
ãŸãšã
ã¢ãã€ãïŒã¢ãããšæ··åããªãã§ãã ããïŒã¯ãã¢ãã€ãã®2ã€ã®æ³åãæºãã2é
æŒç®ã§ããæŒç®ã¯é£æ³çã§ãããäžç«èŠçŽ ïŒãŠãããïŒãååšããå¿
èŠããããŸãã ã¢ãã€ãã®äž»ãªäŸã¯å ç®ãšä¹ç®ã§ãããä»ã«ããããããããŸãã
ïŒã¡ãªã¿ã«ãä¹ç®ã®åäœã¯åäœïŒ1ïŒã§ã all
ãããŒã«å€and
ã§ããã any
ãããŒã«å€or
ã§ããïŒ
äžçªäžã®è¡ïŒæååããªã¹ããããã³ã·ãŒã±ã³ã¹ã¯ãæ¬è³ªçã«åãã¢ãã€ãã§ãã
ãã®ã»ã¯ã·ã§ã³ã¯ã¢ãã€ãã«é¢ããäžé£ã®èšäºã®äžéšã§ãã
èŠããã«ã ã¢ãã€ãã¯ãäžç«èŠçŽ ïŒ ãŠããã ããŸãã¯è±èªã®çšèªã§ã¯identityãšåŒã°ããïŒãæã€é£æ³ãã€ããªæäœã§ãã
ã·ãŒã±ã³ã¹
CïŒã§ã¯ãå€ã®é
延ã·ãŒã±ã³ã¹ã¯IEnumerable<T>
ã䜿çšããŠã¢ãã«åãããŸãã ã·ãŒã±ã³ã¹ã®ãã¢ãçµã¿åãããã«ã¯ãäžæ¹ãä»æ¹ã«è¿œå ããŸãã
xs.Concat(ys)
ããã§ã xs
ãšys
ã¯IEnumerable<T>
ã€ã³ã¹ã¿ã³ã¹ã§ãã Concatæ¡åŒµã¡ãœããã¯ã·ãŒã±ã³ã¹ãçµåããŸãã 次ã®ã·ã°ããã£ããããŸãïŒ IEnumerable<T> Concat<T>(IEnumerable<T>, IEnumerable<T>)
ããããã£ãŠããã€ããªæäœã§ãã é£æ³æ§ãããããŠããããæã£ãŠããããšãããã£ãå Žåãã¢ãã€ãã§ããããšã蚌æããŸãã
èšç®ã®ã·ãŒã±ã³ã¹ã¯çµæãå€æŽããªããããã·ãŒã±ã³ã¹ã¯çµåçã§ãã çµåæ§ã¯ã¢ãã€ãããããã£ã§ããããããããå®èšŒãã1ã€ã®æ¹æ³ã¯ã ããããã£ããŒã¹ã®ãã¹ãã䜿çšããããšã§ãã
[Property(QuietOnSuccess = true)] public void ConcatIsAssociative(int[] xs, int[] ys, int[] zs) { Assert.Equal( xs.Concat(ys).Concat(zs), xs.Concat(ys.Concat(zs))); }
ãã®èªåãã¹ãã§ã¯FsCheckã䜿çšããŸã ïŒã¯ããCïŒã§ãåäœããŸãïŒïŒ Concat
çµåæ§ãå®èšŒããŸãã åé¡ãç°¡çŽ åããããã«ã xs
ã ys
ããã³zs
é
åãšããŠå®£èšãããŠããŸã ã FsCheckã¯é
åã®äœææ¹æ³ããã€ãã£ãã«ç¥ã£ãŠããããããããå¿
èŠã§ããã IEnumerable<T>
ã¯çµã¿èŸŒã¿ã®ãµããŒãããããŸããã ãã¡ãããFsCheck APIã䜿çšããŠèªåã§iEnumerable<T>
äœæããããšãã§ããŸãããããã¯äŸãè€éã«ããæ°ãããã®ãè¿œå ããŸããã çµåæ§ããããã£ã¯ã IEnumerable<T>
ä»ã®çŽç²ãªå®è£
ã«ãé©çšãããŸãã ç§ãä¿¡ããªããªããè©ŠããŠã¿ãŠãã ããã
Operation Concat
ã«ã¯ãŠãããããããŸãã ãŠãããã¯ã次ã®ãã¹ãã§ç¢ºèªããã空ã®ã·ãŒã±ã³ã¹ã§ãã
[Property(QuietOnSuccess = true)] public void ConcatHasIdentity(int[] xs) { Assert.Equal( Enumerable.Empty<int>().Concat(xs), xs.Concat(Enumerable.Empty<int>())); Assert.Equal( xs, xs.Concat(Enumerable.Empty<int>())); }
ã€ãŸãã空ã®ã·ãŒã±ã³ã¹ãã·ãŒã±ã³ã¹ã®å
é ãŸãã¯æ«å°Ÿã«æ¥çãããŠããå Žåãå
ã®ã·ãŒã±ã³ã¹ã¯å€æŽãããŸããã
Concat
ã¯ãŠããããæã€é£æ³ãã€ããªæäœã§ãããããã¢ãã€ãã§ãã 蚌æãããŠããŸãã âŒ
ãªã³ã¯ãªã¹ããšãã®ä»ã®ã³ã¬ã¯ã·ã§ã³
FsCheckã䜿çšããäžèšã®ãã¹ãã¯ã Concat
ãé
åã®ã¢ãã€ãã§ããããšã瀺ããŸããã ãã®ããããã£ã¯ããã¹ãŠã®çŽç²ãªIEnumerable<T>
å®è£
ã«å¯ŸããŠä¿æãããŸãã
Haskellã§ã¯ãé
延ã·ãŒã±ã³ã¹ã¯ãªã³ã¯ãªã¹ããšããŠã¢ãã«åãããŸãã Haskellã®ãã¹ãŠã®åŒãããã©ã«ãã®åŒã§ãããšããçç±ã ãã§ããããã¯æ areã§ãã ã¢ãã€ãã®æ³åã¯ãHaskellã®ãªã¹ãã«ãæå¹ã§ãã
λ> ([1,2,3] ++ [4,5,6]) ++ [7,8,9] [1,2,3,4,5,6,7,8,9] λ> [1,2,3] ++ ([4,5,6] ++ [7,8,9]) [1,2,3,4,5,6,7,8,9] λ> [] ++ [1,2,3] [1,2,3] λ> [1,2,3] ++ [] [1,2,3]
Haskellã§ã¯ã ++
æŒç®åã¯CïŒã®Concat
ãšã»ãŒåãã§ããããã®æäœã¯é£çµã§ã¯ãªãappendãšåŒã°ããŸã ã
FïŒã§ã¯ãFïŒã®ãã¹ãŠã®åŒãããã©ã«ãã®åŒã§ããããããªã³ã¯ãªã¹ãã¯ç©æ¥µçã«ïŒé
延ã§ã¯ãªãïŒåæåãããŸãã ãã ããã¢ãã€ãã®ãã¹ãŠã®ããããã£ããŸã æºããããŠããããããªã¹ãã¯ã¢ãã€ãã®ãŸãŸã§ãã
> ([1; 2; 3] @ [4; 5; 6]) @ [7; 8; 9];; val it : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9] > [1; 2; 3] @ ([4; 5; 6] @ [7; 8; 9]);; val it : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9] > [] @ [1; 2; 3];; val it : int list = [1; 2; 3] > [1; 2; 3] @ [];; val it : int list = [1; 2; 3]
FïŒã§ã¯ãé£çµæŒç®åã¯++
ã§ã¯ãªã@
++
ãããã®åäœã¯Haskellã®å ŽåãšãŸã£ããåãã§ãã âŒ
è¡
ã»ãšãã©ã®ããã°ã©ãã³ã°èšèªã§ããã¹ãå€ãstring
ãšåŒã°ããçç±ãçåã«æã£ãããšã¯ãããŸãããïŒ çµå±ã®ãšãããè±èªã®æååã¯ããŒãã§ãã ãç¹ç¶ã§äœããããã®ãããªé·ãæè»ãªãã®ã§ãã
ããã°ã©ãã³ã°ã§ã¯ãéåžžãããã¹ãã¯ã¡ã¢ãªå
ã§æåã®é£ç¶ãããããã¯ãšããŠè¡šãããŸãã éåžžãããã°ã©ã ã¯ãè¡ã®çµããã®å
åã§ããäœãã«éãããŸã§ããã®ãããªé£ç¶ããã¡ã¢ãªãããã¯ãèªã¿åããŸãã ãããã£ãŠãæååã¯é åºä»ããããŸãã ã·ãŒã±ã³ã¹ãŸãã¯ãªã¹ãã®ããã«èŠããŸãã
å®éãHaskellã§ã¯ã String
åã¯æ±ãã«ãããã®ã§ã¯ãªãã [Char]
å矩èªã§ãïŒããã¯ã Char
å€ã®ãªã¹ãã§ãïŒã ãããã£ãŠãä»ã®ã¿ã€ãã®ãªã¹ãã§ã§ããããšã¯ãã¹ãŠã String
ã§ãã§ããŸãã
λ> "foo" ++ [] "foo" λ> [] ++ "foo" "foo" λ> ("foo" ++ "bar") ++ "baz" "foobarbaz" λ> "foo" ++ ("bar" ++ "baz") "foobarbaz"
æããã«ã String
++
ã¯Haskellã®ã¢ãã€ãã§ãã
åæ§ã«ã.NETã§ã¯ã System.String
ã¯IEnumerable<char>
å®è£
ããŸãã é¡æšã«ãããæã
ã¯ããããã¢ãã€ãã§ããããšãå€æãããšæšæž¬ããããšãã§ããŸã-ãããŠããã¯ã»ãšãã©äºå®ã§ãã èŠãŠã¿ãŸãããããããã¯æ£ç¢ºã«é£æ³çã§ãïŒ
[Property(QuietOnSuccess = true)] public void PlusIsAssociative(string x, string y, string z) { Assert.Equal( (x + y) + z, x + (y + z)); }
CïŒã§ã¯ã +
æŒç®åãstring
ã«å¯ŸããŠå®éã«å®çŸ©ãããŠããããã®FsCheckã®ãã¹ããããããããã«ãããã¯çµåæ§ã§ãã ãããŠã圌ã¯ã»ãšãã©ãŠããããæã£ãŠããŸãã æååã®äžçã§ç©ºã®ãªã¹ãã«çžåœãããã®ã¯äœã§ããïŒ ãã¡ããã空ã®è¡ïŒ
[Property(QuietOnSuccess = true)] public void PlusHasIdentity(NonNull<string> x) { Assert.Equal("" + x.Get, x.Get + ""); Assert.Equal(x.Get, x.Get + ""); }
null
å¿
èŠãªãããšãæåã§FsCheckã«èª¬æããå¿
èŠããããŸããã ãã€ãã®ããã«ã null
ã¯ã³ãŒãã®è°è«ã®éã«æ£ãè»èŒªã«å
¥ããŸãã
ããã§ã®åé¡ã¯ã "" + null
ããã³null + ""
ãåãå€- ""
è¿ããå
¥åå€ïŒ null
ïŒãšçãããªãããšã§ãã ã€ãŸãããã®ç¹æ®ãªã±ãŒã¹ãååšããããã ""
+
æŒç®åã®å®éã®åäœã§""
ãŸããã ïŒãããŠãã¡ãªã¿ã«ã null
null + null
ã¯... ""
è¿ãããã null
ãåäœã§null
ãããŸããïŒãã¡ãããããã ããè¿ããŸã...ïŒã ãã ããããã¯å®è£
ã®æ©èœã§ãã ç·Žç¿ãšããŠã null
ãæã£ãŠããã«ããããããã string
æå¹ãªã¢ãã€ãã«ããCïŒã®ã¡ãœããïŒæ¡åŒµïŒãèããŠã¿ãŠãã ããã æãã€ããšããã«ãHaskellãšåãããã«ãæååã®é£çµã.NETã®ã¢ãã€ãã§ããããšãããã«ç€ºããŸãã âŒ
ç¡æã¢ãââã€ã
以åã®èšäºã§ãæ°åã®å ç®ãšä¹ç®ãã¢ãã€ãã§ããããšã瀺ããããšãæãåºããŠãã ããã å°ãªããšã1ã€ä»¥äžã®æ°ã®ã¢ãã€ãããããããã¯ã·ãŒã±ã³ã¹ã§ãã ãžã§ããªãã¯ã·ãŒã±ã³ã¹ïŒ IEnumerable<T>
ïŒãååšããå Žåãçªå·ãå«ããã¹ãŠãå«ããããšãã§ããŸãã
3
ãš4
2ã€ã®æ°å€ããããããããçµåããããšèããŠããŸãããããããã©ã®ããã«æ£ç¢ºã«çµåãããã¯ãŸã æ確ã§ã¯ãããŸããã ãœãªã¥ãŒã·ã§ã³ã延æããããã«ãäž¡æ¹ã®æ°å€ãåäžã®é
åã«å
¥ããããšãã§ããŸãïŒè±èªã§ã¯ããã¯ã·ã³ã°ã«ãã³é
åãšåŒã°ããŸã-1ã€ã®èŠçŽ ãæã€é
åã§ãããã¯ã·ã³ã°ã«ãã³ãã¿ãŒã³ãšã¯é¢ä¿ãããŸããïŒã
var three = new[] { 3 }; var four = new[] { 4 };
以åã«èšŒæããããã«ãã·ãŒã±ã³ã¹ã¯ã¢ãã€ãã§ãããããå®å
šã«çµã¿åãããããšãã§ããŸãã
var combination = three.Concat(four);
çµæã¯ãäž¡æ¹ã®æ°å€ãå«ãã·ãŒã±ã³ã¹ã§ãã çŸæç¹ã§ã¯æ
å ±ã倱ã£ãŠããªãããããããã®æ°å€ãçµã¿åãããæ¹æ³ãæ確ã«ãªã次第ã以åã«åéããããŒã¿ãèšç®ããã ãã§æžã¿ãŸãã ããã¯ç¡æã¢ãââã€ããšåŒã°ããŸãã
ããšãã°ãæ°å€ã®åèšãååŸããå¿
èŠããããšå€æããŸããã
var sum = combination.Aggregate(0, (x, y) => x + y);
ïŒã¯ãã Sumã¡ãœãããããããšã¯æ¿ç¥ããŠããŸãããçŸåšã®ç®æšã¯è©³çŽ°ãææ¡ããããšã§ãïŒã ãã®Aggregateã¯ãæåã®åŒæ°ãšããŠseed
å€ãåãã2çªç®ãšããŠçµã¿åããé¢æ°ãåããŸãã
ãããŠãããªãã¯è£œåãæã«å
¥ããããšãã§ããŸãïŒ
var product = combination.Aggregate(1, (x, y) => x * y);
ã©ã¡ãã®å Žåãã seed
å€ã¯å¯Ÿå¿ããã¢ãã€ãæŒç®ã®1ã§ããããšã«æ³šæããŠãã ãã0
ã¯å ç®ã 1
ã¯ä¹ç®ã§ãã åæ§ã«ãéèšé¢æ°ã¯ã察å¿ããã¢ãã€ããåç
§ãããã€ããªæŒç®ã䜿çšããŸãã
èå³æ·±ãããšã«ãããã¯ãç¡æã¢ãã ãã«äŒŒããç¡æã¢ãã€ãããšåŒã°ããŸãã ã©ã¡ãã®å Žåã§ãããã¹ãŠã®ããŒã¿ãåéããŠããã«è§£éããããšã¯ã§ããŸããããã®åŸãäºåã«æºåãããå€ãã®ãèšç®æ©ãã®ããããã«ãã®ããŒã¿ãããŒãããŸãã
ãŸãšã
.NETã®ã·ãŒã±ã³ã¹ãé
åãFïŒãHaskellã®ãªã¹ããªã©ãå€ãã®ã¿ã€ãã®ã³ã¬ã¯ã·ã§ã³ã¯ãé£çµã«å¯Ÿããã¢ãã€ãã§ãã Haskellã§ã¯ãæååã¯ãªã¹ãã§ãããããæååã®é£çµã¯èªåçã«ã¢ãã€ãã«ãªããŸãã .NETã§ã¯ãæååã®+
æŒç®åã¯ã¢ãã€ãã§ããã null
ãååšããªããµããããå Žåã®ã¿ã§ãã ãã ãããããã¯ãã¹ãŠåãã¢ãã€ãã®ããªãšãŒã·ã§ã³ã§ãã
åã®ããŒãã§ç€ºããããã«ãè¿œå ã¯ãã¹ãŠã®ã¢ãã€ãã®äžã§æãçŽæçã§ãèªç¶ãã§ãããããCïŒã+
ã䜿çšããŠæååãé£çµããã®ã¯è¯ãããšã§ãã ããªãã¯åŠæ ¡ã®ç®æ°ãç¥ã£ãŠããã®ã§ãè¿œå ã®æ¯phorãããã«ç解ã§ããŸãã ããããã¢ãã€ãã¯æ¯phor以äžã®ãã®ã§ãã ããã¯ç¹å¥ãªãã€ããªæŒç®ã説æããæœè±¡æŠå¿µã§ããããã®1ã€ïŒãããèµ·ãã£ãïŒã¯å ç®ã§ãã ããã¯æŠå¿µã®äžè¬åã§ãã ãããã¯ãã§ã«ç¥ã£ãŠããæœè±¡åã§ãã
ãããã«
ããã§ãã®èšäºã¯çµããã§ãã ããã¯ãªã³ã¯ã§ãªã³ã¯ãããHabréãžã®é£ç¶ããæçš¿ãšãã圢ã§ããªãªãžãã«ãšåãæ¹æ³ã§å
¬éãããæ
å ±ããŸã ãããããããŸãã 以äžïŒèšäºã®ãªãªãžãã«ã¯Â©Mark Seemann 2016ã翻蚳ã¯JUG.ru Groupãã翻蚳è
ã¯Oleg Chirukhinã§ãã
2017幎 11æ12ã13æ¥ã«ã¢ã¹ã¯ã¯ã®ã¹ã©ãã£ã³ã¹ã«ã€ã©ãã£ãœã³ã§éå¬ãããDotNext 2017ã¢ã¹ã¯ã¯äŒè°ã«ã¢ã¯ã»ã¹ããŠãèè
ãšã©ã€ãã§ãã£ããã§ããŸãã ããŒã¯ã¯ãäŸåæ§æ³šå
¥ããäŸåæ§æåŠãŸã§ãã«é¢ããè¬æŒãèªã¿ãŸãã ãã±ããã¯ãã¡ãã§å
¥æã§ããŸã ã