ä»æ¥ãæè¡èšäºã®ç¿»èš³ãæäŸããããšæããŸãããã®èè ã§ããThomas Petrichekã¯ãFïŒã§ã©ã€ãã©ãªãæäœããããŸããŸãªåŽé¢ãæ€èšããŠããŸãã çŸåšãèè ãåå ãã1åã®æ¬ã®å¯èœæ§ãç 究ããŠããããããã®èšäºã¯äž»ã«ãµã³ãã«ããã¹ããšããŠäœçœ®ä»ããããŸãããã®äŸã§ã¯ãèè ã®ç©èªã®æèœã圌ã®ã¢ã€ãã¢ã®è³ªãè°è«ãæšè«ãããã³ã³ãŒãäŸãè©äŸ¡ã§ããŸãã ãã ãããã®èšäºã«èšèŒãããŠããèæ ®äºé ã¯FïŒã§ã®äœæ¥ã«éå®ããããã®ã§ã¯ãªãããããã®èšäºãå¹ åºãèªè ã«ãšã£ãŠæçã§èå³æ·±ããã®ã«ãªãããšãé¡ã£ãŠããŸãã
ãã®èšäºã¯ãæ©èœã©ã€ãã©ãªã®èšèšã«é¢ãã以åã®æçš¿ã® 1ã€ã«åºã¥ããŠæžãããŸããããå¥ã®ãããã¯ã«å°å¿µããŠããããããã®ãããªçŽ¹ä»èšäºããªããŠãéåžžã«ç解ããããã§ãããã
åã®èšäºã§ãé¢æ°åã¹ã¿ã€ã«ã§ã©ã€ãã©ãªãäœæããéã«åœ¹ç«ã€ããã€ãã®ååã説æããŸããã FïŒã§ã©ã€ãã©ãªãäœæããéã®ç§èªèº«ã®çµéšã«äŸåããŠããŸãããããã§çŽ¹ä»ããã¢ã€ãã¢ã¯éåžžã«æ®éçã§ãããããã°ã©ãã³ã°èšèªã䜿çšããéã«åœ¹ç«ã¡ãŸãã 以åã®æçš¿ã§ãè€æ°ã¬ãã«ã®æœè±¡åã«ãããã·ããªãªã®80ïŒ ã®å®è£ ãç°¡çŽ åããã©ã€ãã©ãªãäœæããæ¹æ³ãæžããããããèå³æ·±ãå®çšçãªã±ãŒã¹ã§ã圹ç«ã¡ãŸãã
ãã®èšäºã§ã¯ãä»ã®2ã€ã®åŽé¢ã«ã€ããŠèª¬æããŸããæ§æå¯èœãªã©ã€ãã©ãªãéçºããæ¹æ³ãšãã©ã€ãã©ãªãéçºãããšãã«ã³ãŒã«ããã¯ãåé¿ããæ¹æ³ïŒãããŠæãéèŠãªçç±ïŒã§ãã èšäºã®ååã瀺ãããã«ããã®æ¬è³ªã¯æ¬¡ã®ããã«èŠçŽãããŸãïŒãã¬ãŒã ã¯ãŒã¯ã§ã¯ãªãã©ã€ãã©ãªãæžããŸãïŒ
ãã¬ãŒã ã¯ãŒã¯ãšã©ã€ãã©ãªã®æ¯èŒ
ãã¬ãŒã ã¯ãŒã¯ãšã©ã€ãã©ãªã®éãã¯äœã§ããïŒ äž»ã«ãããã®äœ¿çšæ¹æ³ãããã³æåãš2çªç®ã®å Žåã®ã³ãŒãã®æ§è³ªã¯ã©ããªããŸããã
- ãã¬ãŒã ã¯ãŒã¯ ãã¬ãŒã ã¯ãŒã¯ã䜿çšããå Žåããã®ã¿ã¹ã¯ã¯ã·ã¹ãã ã®åäœãä¿èšŒããããšã§ãã å®è£ ãæ¥ç¶ããæ¡åŒµãã€ã³ãïŒã€ã³ã¿ãŒãã§ã€ã¹ïŒã®æ°ãå®çŸ©ããŸãã
- å³æžé€š ã©ã€ãã©ãªã䜿çšãããšãã¯ãã·ã¹ãã ã®æäœã«è²¬ä»»ããããŸãã ã©ã€ãã©ãªã¯ãã¢ã¯ã»ã¹ã§ããå€ãã®ãã€ã³ãïŒé¢æ°ãšã¿ã€ãïŒãå®çŸ©ããã³ãŒãã¯å¿ èŠã«å¿ããŠããããåŒã³åºããŸãã
äžã®å³ã«éãã瀺ããŸãã ãã¬ãŒã ã¯ãŒã¯ã¯ãèšå ¥ããå¿ èŠãããæ§é ãå®çŸ©ããã©ã€ãã©ãªèªäœã«ã¯ãã³ãŒããæ§ç¯ããããã®æ§é ããããŸãã
ãã¡ãããã©ã€ãã©ãªãšãã¬ãŒã ã¯ãŒã¯ãžã®ãã®ãããªåå²ã¯æ確ã§ãã äžéšã®ã³ã³ããŒãã³ãã¯ã1çªç®ãš2çªç®ã®æ©èœãçµã¿åãããŠããŸããã©ã€ãã©ãªãªã©ã®ã³ã³ããŒãã³ããåŒã³åºããŸãããç¹å®ã®ãããïŒããšãã°ãã€ã³ã¿ãŒãã§ãŒã¹ïŒãå ¥åããå¿ èŠããããŸãã
ãã¬ãŒã ã¯ãŒã¯ã®äœãåé¡ã«ãªã£ãŠããŸããïŒ
äžèšã®å³ã確èªãããšããã¬ãŒã ã¯ãŒã¯ã§ã©ã®ãããªåé¡ãçºçãããããã§ã«ç¢ºèªã§ããŸãã ãã®ã»ã¯ã·ã§ã³ã§ã¯ããã®ãããª3ã€ã®åé¡ã«é¢ããããã€ãã®ããšã説æããŸãïŒæ¬¡ã®ã»ã¯ã·ã§ã³ã§ã¯ããããã解決ããæ¹æ³ã«ã€ããŠèª¬æããŸãïŒã
ãã¬ãŒã ã¯ãŒã¯ã¯æ§æããŸãã
ããããããã¬ãŒã ã¯ãŒã¯ã®æ倧ãã€æãæçœãªåé¡ã¯ããã¬ãŒã ã¯ãŒã¯ãåããªãããšã§ãã ãã¬ãŒã ã¯ãŒã¯ã2ã€ããå Žåãããããã«ç¬èªã®ç¹å®ã®ããããããããããåããå¿ èŠããããŸãã ããããéåžžããããã¬ãŒã ã¯ãŒã¯ãå¥ã®ãã¬ãŒã ã¯ãŒã¯ã«æ¿å ¥ããæ¹æ³ã¯ãããŸããïŒãããŠãéåžžã1ã€ã®ãã¬ãŒã ã¯ãŒã¯ãæ¡ä»¶ä»ãã§å åŽã«ãããä»ã®ãã¬ãŒã ã¯ãŒã¯ãå€åŽã«ããçç±ã¯æ確ã§ã¯ãããŸããïŒã
ã©ã€ãã©ãªã®ç¶æ³ã¯ç°ãªããŸãã ãããã管çãããããããã°ã©ã ã§å€ãã®ã©ã€ãã©ãªãåŒã³åºãããšãã§ããŸãã ãã¡ãããããã«ã¯ããã€ãã®å°é£ã䌎ããŸã-ã©ã€ãã©ãªã®ãšã³ããã€ã³ãã®åšãã«ããè€éãªã³ãŒããæžãå¿ èŠããããŸã-ããããååãšããŠãããã¯éåžžã«å®è¡å¯èœã§ãã
çè«çåŸé
ç§ã¯ã次ã®èæ ®äºé ã«çè«çæ ¹æ ããããšäž»åŒµããŠããŸãããããã¬ãŒã ã¯ãŒã¯ã¯ã¢ããã«å°ã䌌ãŠããŸãã ã¢ããã®å€ã«ããå Žåã¯ãã¢ãžã¥ãŒã«ã䜿çšããŠã¢ããããäžã«å ¥ãããããšãã§ããŸãã ãã®åŸãã¢ããå ã§ããŸããŸãªæäœãå®è¡ã§ããŸãããããããæãåºãããšã¯ã§ããŸããã ãã¬ãŒã ã¯ãŒã¯ã¯ãããã®ã¢ããã«äŒŒãŠããŸãã
ã¢ããã®æ§æãé£ããããšã¯ããç¥ãããŠããŸãïŒãã¬ãŒã ã¯ãŒã¯ãåæ§ïŒã ã¢ããM1ãšM2ãããå ŽåãM1ïŒM2αïŒâM2ïŒM1αïŒã®æäœã䜿çšããŠãããã³ã°ã§ããŸãã å ã¿èŸŒãã¢ãããšå ã¿èŸŒãã¢ãããå ¥ãæ¿ããŸãã ãã¬ãŒã ã¯ãŒã¯ã§ãåæ§ã®ããšãã§ããŸããïŒ
ãã¬ãŒã ã¯ãŒã¯ãæ¢çŽ¢ããã®ã¯é£ããã§ãã
ãã¬ãŒã ã¯ãŒã¯ã®ãã1ã€ã®å€§ããªåé¡ã¯ããã¬ãŒã ã¯ãŒã¯ã®ãã¹ããšç 究ãé£ããããšã§ãã FïŒã§ã¯ãã©ã€ãã©ãªãFïŒã€ã³ã¿ã©ã¯ãã£ãç°å¢ã«ããŒãããããŸããŸãªå ¥åãªãã·ã§ã³ã§å®è¡ããŠã©ã€ãã©ãªã®æ©èœã確èªãããšéåžžã«äŸ¿å©ã§ãã ããšãã°ãSuave Webéçºã©ã€ãã©ãªã䜿çšããŠã次ã®ãããªç°¡åãªWebãµãŒããŒãå®è¡ã§ããŸãã
// #r "Suave.0.25.0/lib/net40/Suave.dll" open Suave.Web open Suave.Http // -, hello startWebServer defaultConfig <| fun ctx -> async { let whoOpt = ctx.request.queryParam "who" let message = sprintf "Hello %s" (defaultArg whoOpt "world") return! ctx |> Successful.OK message }
ãã®ãã©ã°ã¡ã³ãã¯ã©ã€ãã©ãªãŒãããŒãããŠãããããã©ã«ãã®æ§æãšèŠæ±ãåŠçããããã®é¢æ°ã䜿çšããŠstartWebServerãåŒã³åºããŸãïŒé¢æ°ã¯whoèŠæ±ãã©ã¡ãŒã¿ãŒãåãåããã°ãªãŒãã£ã³ã°ã衚瀺ããŸãïŒã
ãŠãŒã¶ãŒãã©ã€ãã©ãªããã°ããè©Šãããšãã§ããããããã®æ¹æ³ã¯éåžžã«äŸ¿å©ã§ãã
ããŸããŸãªãã©ã¡ãŒã¿ãŒã§startWebServerãåŒã³åºããŠããããäœããããïŒãŸãã¯ãä»ã®é¢æ°ã®å Žåã¯äœãè¿ããïŒã確èªããŠãã ããã
çè«çåŸé
ã©ã€ãã©ãªãšãã¬ãŒã ã¯ãŒã¯ã®éãã¯ãé¢æ°åŒã³åºããšåŒæ°ãšããŠé¢æ°ãæå®ããå¿ èŠæ§ãšã®éã«ååšãããã®ãšãã䌌ãŠããŸãã
libïŒÏ1âÏ2ïŒã©ã€ãã©ãªïŒ
fwkïŒïŒÏ2âÏ1ïŒâåäœïŒãã¬ãŒã ã¯ãŒã¯ïŒ
ã©ã€ãã©ãªã®å Žåãlibé¢æ°ãåŒã³åºãããšãã§ããããã«ãÏ1ã®å€ãäœæããå¿ èŠããããŸãã ã©ã€ãã©ãªã¯ãÏ1ãäœæããä»ã®é¢æ°ãæäŸããå ŽåããããŸãïŒãã®å Žåããã®ãããªãã§ãŒã³ããæåã®é¢æ°ãèŠã€ããŠåŒã³åºãã ãã§ãïŒã 察話çã«ã³ãŒããèšè¿°ããå ŽåãÏ1ã®ç°ãªãå€ãèšå®ããŠãé¢æ°ãå®è¡ããäœãè¿ããããã確èªã§ããŸãã ãããã£ãŠãã©ã€ãã©ãªã®åäœïŒããã³å¿ èŠãªãã®ãå®çŸããããã®ã©ã€ãã©ãªã®äœ¿çšæ¹æ³ïŒãç°¡åã«èª¿ã¹ãããšãã§ããŸãã ããã«ããã®å Žåãã©ã€ãã©ãªã䜿çšããã³ãŒãã®ãã¹ããç°¡çŽ åãããŸãã
ãã¬ãŒã ã¯ãŒã¯ã®å Žåãããè€éãªç¶æ³ãçºçããŸãã Ï2ãåããÏ1ãçæããé¢æ°ãäœæããå¿ èŠããããŸãã æåã®åé¡ã¯ãããŸããŸãªç¶æ³ã§Ï2ã®å€ãã©ã®ããã«åãåãããååã«ç解ããŠããªãããšã§ãã çæ³çãªäžçã§ã¯ããç¡å¹ãªå€ã¯è¡šçŸã§ããªããããå®éã«ã¯ãæãäžè¬çãªã±ãŒã¹ãäž»ã«åŠçããã³ãŒãã®èšè¿°ãéå§ãããã æãŸããåäœãå®çŸããããã«ãÏ1ã®ã©ã®å€ãäžããã¹ãããç解ïŒããã³èª¿æ»ïŒããããšãé£ãããããŸããã
ããŠãSuaveã®äŸã«æ»ããšãèªè ã¯å°ãããããããŸãããããã¯ã©ã€ãã©ãªïŒé¢æ°ãåŒã³åºãïŒããã¬ãŒã ã¯ãŒã¯ïŒåŒã³åºãã¹ãé¢æ°ã瀺ãïŒãªã®ã§ããããã å®éãäžèšã®äŸã¯äž¡æ¹ã®åŽé¢ã瀺ããŠããŸãã åŸã§ç€ºãããã«ããã®ãããªããã¬ãŒã ã¯ãŒã¯ãæ§é ã®ããªã¢ã³ãã¯ããã»ã©æªãã¯ãããŸããïŒä»¥äžã®ã³ãŒã«ããã¯ãšéåæã®ã»ã¯ã·ã§ã³ãåç §ããŠãã ããïŒã
ãã¬ãŒã ã¯ãŒã¯ã¯ãã³ãŒãã®æ§æã決å®ããŸãã
ãã¬ãŒã ã¯ãŒã¯ã®æ¬¡ã®åé¡ã¯ããã¬ãŒã ã¯ãŒã¯ãã³ãŒãã®æ§é ã決å®ããããšã§ãã ãã®ãããªå Žåã®å žåçãªäŸïŒç¹å®ã®åºæ¬ã¯ã©ã¹ããã®ç¶æ¿ãšç¹å®ã®ã¡ãœããã®å®è£ ãå¿ èŠãšãããã¬ãŒã ã¯ãŒã¯ã䜿çšããŠããŸãã ããšãã°ãXNAãã¬ãŒã ã¯ãŒã¯ã®Gameã¯ã©ã¹ã¯æ¬¡ã®ããã«ãªããŸãïŒXNAãæ»ãã§ããããšã¯ç¥ã£ãŠããŸããããã®ãã¿ãŒã³ã¯ä»ã®åæ§ã®ãã¬ãŒã ã¯ãŒã¯ã§ã䜿çšãããŠããŸãïŒã
class Game { abstract void Initialize(); abstract void Draw(DrawingContext ctx); abstract void Update(); }
åæåã§ã¯ãã²ãŒã ã§å¿ èŠãšãªãå¯èœæ§ã®ãããªãœãŒã¹ãããŒãããããšãåæãšããŠããŸãã 次ã®ç¶æ ãèšç®ããããã«Updateãç¹°ãè¿ãåŒã³åºãããç»é¢ãæŽæ°ããå¿ èŠããããšãã«DrawãåŒã³åºãããŸãã ã€ã³ã¿ãŒãã§ã€ã¹ã¯ãåœä»€åããã°ã©ãã³ã°ã¢ãã«ã«æ確ã«çŠç¹ãåãããŠããããã以äžã«ç€ºããã®ã³ãŒããã©ã°ã¡ã³ãã®ãããªãã®ãåŸãããŸãã ããã§ã¯ããããªãªãã§ã²ãŒã ã®æããªããŒãžã§ã³ãäœæããŸããããªãªã¯ãå·Šããå³ã«ãã£ãããšç§»åããŸãã
type MyGame() = inherit Xna.Game() let mutable x = 0 let mutable mario = None override this.Initialize() = mario <- Some(Image.Load("mario.png")) override this.Update() = x <- x + 1 override this.Draw(ctx) = mario |> Option.iter (fun mario -> ctx.Draw(x, 0, mario))
ãã®ãããªãã¬ãŒã ã¯ãŒã¯æ§é ã¯ããã®äžã«çŸããã³ãŒããæžãããšã«è²¢ç®ããŸããã ããã§ã¯ãæãç°¡åãªå®è£ ãå¯èœã«ããŸããã å€æ°ãã£ãŒã«ãxã¯ããªãªã®å Žæã«å¯Ÿå¿ããããªãªã¯ãªãœãŒã¹ãä¿åããããã®ãªãã·ã§ã³å€ã§ãã
CïŒã§ã¯ãåæ§ã®ã³ãŒããããçŸãããªããšäž»åŒµããããšãã§ããŸãïŒããšãã°ããã¹ãŠã®FïŒãã£ãŒã«ããåæåããå¿ èŠãããããããªãã·ã§ã³å€ã䜿çšããå¿ èŠããããŸããïŒããããã¯ãã§ãã¯ãå®å šã«ç¡èŠããå Žåã«ã®ã¿åœãŠã¯ãŸããŸãã å®éãããã§ãªãã·ã§ã³å€ã䜿çšããŠãã³ãŒããããå®å šã«ããŸãïŒåæåããŠããªããšèª€ã£ãŠDrawã§ããªãªã䜿çšã§ããªãããïŒã ãŸãã¯ããã¬ãŒã ã¯ãŒã¯ã¯ãDrawã®åã«Initializeãåžžã«åŒã³åºãããããšãä¿èšŒããŸããïŒ ã©ããã£ãŠãããç¥ãã®ã§ããïŒ
ãã¬ãŒã ã¯ãŒã¯ã®ãåãããé¿ããæ¹æ³
ã©ã€ãã©ãªãäœæããæ¹ããã¬ãŒã ã¯ãŒã¯ãäœæãããããåªããŠãããšçŽåŸã§ããããšãé¡ã£ãŠããŸãã ãããããããŸã§ã®ãšããããããã©ã®ããã«è¡ããããã«ã€ããŠãå ·äœçãªã¢ããã€ã¹ã¯ããŠããŸããã ãã®èšäºã®æ®ãã®éšåã§ã¯ãããã€ãã®ç¹å®ã®äŸãæ€èšããŸãã
ã€ã³ã¿ã©ã¯ãã£ããªç 究ããµããŒã
FïŒã§ã©ã€ãã©ãªãäœæããŠããªãå Žåã§ããFïŒInteractiveã䜿çšããŠãã€ã³ã¿ã©ã¯ãã£ãã«äœ¿çšã§ããããã«ããå¿ èŠããããŸãã ãã€ã³ãã¯ãFïŒèšèªãã©ã€ãã©ãªã®ããã¥ã¡ã³ãåã«å®å šã«é©åããŠããã ãã§ãªããã€ã³ã¿ã©ã¯ãã£ãã¹ã¯ãªãããèšè¿°ããããšã§ãã©ã€ãã©ãªãåŒã³åºãã®ãéåžžã«ç°¡åã«ãªãããšã確èªã§ããŸãïŒ.NETãã©ãããã©ãŒã ã§äœæ¥ããŠããå Žåã¯ããªãã·ã§ã³ã¯LINQPadãšé£æºããããšã§ãïŒã
2ã€ã®äŸã䜿çšããŠãæšè«ã説æããŸãã æåã®ã³ãŒãã¹ããããã¯ã FïŒFormattingã©ã€ãã©ãªã䜿çšããŠãFïŒã¹ã¯ãªãããã¡ã€ã«ãšMarkdownããã¥ã¡ã³ããå«ãããã¥ã¡ã³ããã£ã¬ã¯ããªãHTMLãã¡ã€ã«ã«å€æããæ¹æ³ããŸãã¯å¥ã®ãã¡ã€ã«ãåŠçããæ¹æ³ã瀺ããŠããŸãã
#r "FSharp.Literate.dll" open FSharp.Literate // Literate.ProcessDirectory("C:/demo/docs") // Literate.ProcessMarkdown("C:/demo/docs/sample.md") Literate.ProcessScriptFile("C:/demo/docs/sample.fsx")
ãã€ã³ãã¯ãã©ã€ãã©ãªãåç §ããåå空éãéãããšã³ããªãã€ã³ããšããŠLiterateã¿ã€ããèŠã€ããå¿ èŠãããããšã§ãã ããã«ããããããã䜿çšã§ããŸãã ãããŠããªããæã£ãŠãããã®ãåç §ããŠãã ããïŒ
ãã¹ãŠã®åªããã©ã€ãã©ãªããã®ãã©ã¯ãã£ã¹ããµããŒãããã¯ãã ãšæããŸãã å¥ã®äŸãšããŠãFïŒã³ãŒããJavaScriptã«å€æããFunScriptãèŠãŠã¿ãŸãããã ååãšããŠãWebãã¬ãŒã ã¯ãŒã¯ã®äžéšãšããŠäœ¿çšãããŸãããããèªäœã§æ£åžžã«æ©èœããŸãã 次ã®ã¹ããããã¯ãåçŽãªéåæã«ãŒãçšã®JavaScriptã³ãŒããçæããŸãããã®ã«ãŒãã¯ãããŒãžããšã®æ°ã1ã€å¢ãããŸãã
#r "FunScript.dll" #r "FunScript.TypeScript.Binding.lib.dll" open FunScript open FunScript.TypeScript Compiler.compile <@ let rec loop n : Async<unit> = async { Globals.window.document.title <- string n do! Async.Sleep(1000) return! loop (n + 1) } loop 0 @>
ç¹°ãè¿ããŸãããã©ã€ãã©ãªïŒãã®å Žåã¯DOMãã€ã³ãã£ã³ã°ïŒãåç §ãã1ã€ã®é¢æ°ãåŒã³åºããŸããã³ã³ãã€ã«é¢æ°ã¯FïŒåŒçšç¬Šãåãå ¥ããŸãã ãããçºèŠããããããªãã¯ãããèªåã§è©Šãããšãã§ããŸããããã¯äœãæ±ãããšãã§ããŸãïŒ åã®äŸã¯ãFïŒasync {...}ã®çŸãããµããŒããšãDOMãžã®ã¢ã¯ã»ã¹ãå¯èœã«ãããã€ã³ãã£ã³ã°ã瀺ããŠããŸãã
åçŽãªã³ãŒã«ããã¯ã®ã¿ã䜿çšãã
äžèšã®çè«çäœè«ã§ãã¬ãŒã ã¯ãŒã¯ã«ã€ããŠè©±ãããšããæ¬è³ªçã«ãé¢æ°ãåŒæ°ãšããŠåãæ§é ã¯ãã¬ãŒã ã¯ãŒã¯ãšåŒã°ããããšã«æ³šæããŸããã é«éé¢æ°ã䜿çšãã¹ãã§ã¯ãªããšããããšã§ããïŒ ãã¡ããéããŸãïŒ
次ã®2ã€ã®åçŽãªãã©ã°ã¡ã³ããæ¯èŒããŸãã1ã€ç®ã¯ãªã¹ãã®åŠçã«æšæºé¢æ°ã䜿çšãã2ã€ç®ã¯ç¹å®ã®å ¥åãèªã¿åãïŒ1ã€ç®ã®é¢æ°ã䜿çšïŒã次ã«æ€èšŒããã³åŠçïŒ2ã€ç®ã®é¢æ°ã䜿çšïŒããŸãã
// [ 1 .. 10 ] |> List.filter (fun n -> n%3 = 0) |> List.map (fun n -> n*10) // , , // readAndProcess (fun () -> File.ReadAllText("C:/demo.txt")) (fun s -> s.ToUpper())
æåã®äŸãš2çªç®ã®äŸã«ã¯2ã€ã®éãããããŸãã ãªã¹ãåŠçé¢æ°ã䜿çšããå ŽåãåŒæ°ãšããŠåžžã«1ã€ã®é¢æ°ã®ã¿ãæå®ããŸãã ããã«ããã®ãããªé¢æ°ã¯æ±ºããŠã¹ããŒããã«ã§ãã£ãŠã¯ãªããŸããã
2çªç®ã®å Žåã2ã€ã®æ©èœã瀺ãããŸãã ç§ã®æèŠã§ã¯ãããã¯é¢æ°ãå¿ èŠä»¥äžã«è€éã§ããããšãå€æããå åã§ãã
次ã«ãreadAndProcessã¯ãæåã®é¢æ°ããæååã®ç¶æ ãè¿ãã2çªç®ã®é¢æ°ãžã®å ¥åãšããŠæååãåãå ¥ããããã«ããŸãã ããã¯å¥ã®æœåšçãªåé¡ã§ãã æåã®é¢æ°ãã2çªç®ã®é¢æ°ã«ä»ã®ç¶æ ã転éããå¿ èŠãããå Žåã¯ã©ããªããŸããïŒ
ãã¡ãããããã§ã¯ç°¡åãªã±ãŒã¹ãæ€èšããŠããŸãããreadAndProcessã®å éšã§äœãèµ·ãããèŠãŠã¿ãŸãããã ãã®é¢æ°ã¯ããã€ãã®äŸå€ãåŠçããæåã«å ¥åã®æå¹æ§ããã§ãã¯ãããã®åŸã§2çªç®ã®åŒæ°ãåŒã³åºããŸãã
let readAndProcess readInput processInput = try let input = readInput() if input = null || input = "" then None else Some(processInput input) with :? System.IO.IOException -> None
ãã®æœè±¡åã¯ã©ã®ããã«æ¹åã§ããŸããïŒ ãŸãããã®é¢æ°ã¯å®éã«2ã€ã®åé¡ã解決ããŸãã ãŸããäŸå€ãåŠçããŸãïŒããªãæãã§ãããããã¯ã±ãŒã¹ã¹ã¿ãã£ã§ãïŒã 次ã«ãå ¥åãæ€èšŒããŸãã ããã2ã€ã®æ©èœã«åå²ã§ããŸãã
let ignoreIOErrors f = try Some (f()) with :? System.IO.IOException -> None let validateInput input = if input = null || input = "" then None else Some(input)
çŸåšãvalidateInputã¯ãå ¥åãæå¹ãªå Žåã«Someãè¿ãæãäžè¬çãªé¢æ°ã«ãªããŸãã ignoreIOErrorsé¢æ°ã¯ãŸã é¢æ°ãåŒæ°ãšããŠäœ¿çšããŸã-äŸå€åŠçã¯äžéãã¿ãŒã³ã®ããŒã«ã®å žåçãªäŸã§ããããããã®å Žåã¯ãå§ãã§ãã ããªããæžãããšãã§ããæ°ããé¢æ°ã䜿çšããŠïŒ
ignoreIOErrors (fun () -> let input = File.ReadAllText("C:/demo.txt") validateInput input |> Option.map (fun valid -> valid.ToUpper() ))
è©ŠããŠã¿ããšãããã§3è¡ãæºããããšãã§ããŸãããã³ãŒãã¯å°ãé·ããªããå°ãæ確ã«ãªããŸãã
ç§ã®æèŠã§ã¯ãããã¯ãã©ã¹ã§ããäœãèµ·ãã£ãŠããã®ãããããã®ã§ïŒãããŠãvalidateInputã®ã€ã³ã¿ã©ã¯ãã£ããªåŒã³åºãããå§ããããšãã§ããŸãïŒïŒããã«ãreadAndProcessé¢æ°ã奜ãå Žåããããè¯ãã§ã-äžèšã®2ã€ã®é¢æ°ã䜿çšããŠç°¡åã«æ±ºå®ã§ããŸãïŒãã®éã§ã¯ãããŸããïŒïŒãããã£ãŠãã©ã€ãã©ãªã¯ãã«ãã¬ãã«ã®æœè±¡åãæäŸã§ããŸãã ããã«ã€ããŠã¯ãåã®èšäºã§èª¬æããŸããã ããããé«ã¬ãã«ã®æœè±¡åã®ã¿ãæäŸããå Žåãããã¯å¯èœæ§ãå¶éããŸãã
èŠçŽãããšãåŒæ°ãšããŠé¢æ°ãæž¡ãããšã¯å¯èœã§ããã泚æãå¿ èŠã§ãã é¢æ°ãåŒæ°ãšããŠ2ã€ä»¥äžã®é¢æ°ãåãå Žåãããã¯ããããæé«ã®äœã¬ãã«ã®æœè±¡åã§ã¯ãããŸããã åŒæ°ãšããŠå ±åãããé¢æ°ãåé¢ããŠäœããã®ç¶æ ãæž¡ãå¿ èŠãããå Žåã¯ã確å®ã«ä»£æ¿æ段ãæäŸããå¿ èŠããããŸãïŒåŒã³åºãåŽããæšæºãç¶æ 転éã§ã¯ãªããäœãä»ã®ãã®ãå¿ èŠãšããå ŽåïŒã
ã€ãã³ããšéåæã䜿çšããŠã³ãŒã«ããã¯ãå転ãã
ãã¬ãŒã ã¯ãŒã¯ãã³ãŒãã®æ§æã«ã©ã®ããã«åœ±é¿ãããã«ã€ããŠãç°¡åãªã²ãŒã ãšã³ãžã³ãäŸã«æããŸããã å¯å€ãã£ãŒã«ãã䜿çšããŠç¹å®ã®ã¯ã©ã¹ãå®è£ ããå¿ èŠããªãããã«ãå¥ã®æ¹æ³ã§äœãã§ããã§ããããïŒ FïŒã§ã¯ãéåæã¯ãŒã¯ãããŒãšã€ãã³ãé§ååããã°ã©ãã³ã°ã¢ãã«ã䜿çšã§ããŸãã
ç¶æ³ã¯ãèšç®åŒïŒããã³ãã®ãããªæ©èœãã·ãã¥ã¬ãŒãã§ããã€ãã¬ãŒã¿ïŒã®ãããªèšèªã§ã¯è€éã§ãããCïŒã¯awaitããµããŒãããFïŒã¯Haskellã§èšç®åŒãæã¡ãŸã-è¡šèšæ³ãå®è¡ããããããPythonã§æªçšã§ããŸããžã§ãã¬ãŒã¿ãŒã
å®è£ ããå¿ èŠãããä»®æ³ã¡ãœãããèšè¿°ãã代ããã«ãæäœãå¿ èŠãªãšãã«èµ·åããã€ãã³ããæäŸãããšããèãæ¹ã§ãã ãããã£ãŠãGameã¯ã©ã¹ã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯æ¬¡ã®ããã«ãªããŸãã
type Game = member Update : IEvent<unit> member Draw : IEvent<DrawingContext> member IsRunning : bool
FïŒasyncã䜿çšããå Žåãç°ãªãæ¹æ³ã§ã³ãŒããäœæã§ããŸãã ãã¬ãŒã ã¯ãŒã¯ãšã©ã€ãã©ãªãæ¯èŒãããšããå ã®åæã«æ»ããšãçºçãããã¹ãŠãå®å šã«å¶åŸ¡ã§ããŸãã 次ã®äŸã§ã¯ããªãœãŒã¹ãšGameãªããžã§ã¯ããåæåããAwaitObservableã¡ãœããã䜿çšããŠUpdateãŸãã¯Drawã€ãã³ããåŸ æ©ããã«ãŒãïŒååž°çãªéåæãããã¯ã䜿çšïŒãå®è£ ããŸãã
// let game = Inverted.Game() let mario = Image.Load("mario.png") // , let rec loop x = async { if game.IsRunning then let! evt = Async.AwaitObservable(game.Update, game.Draw) match evt with | Choice1Of2() -> // 'Update' return! loop (x + 1) | Choice2Of2(ctx) -> // 'Draw' ctx.Draw(x, 0, mario) return! loop x } // Game x=0 loop 0
ãã¡ãããã²ãŒã ã®ç¶æ ãæŽæ°ããããç»é¢ãåæç»ãããããããã«ã·ã¹ãã ãããã€é»è©±ãåãåããããããªãããã絶察çãªå¶åŸ¡ãå®çŸããããšã¯ã§ããŸããã ãã ãããªãœãŒã¹ã®åæåãå®å šã«å¶åŸ¡ããã²ãŒã ã®é²è¡ç¶æ³ã確èªããŠã1ã€ãŸãã¯å¥ã®ã€ãã³ããåŸ ã€ããšãã§ããŸãã
ããã§éèŠãªã®ã¯ãéåæ{...}ã®äœ¿çšã§ãã AwaitObservableã䜿çšããŠããUpdateãŸãã¯Drawãå¿ èŠãªãšãã«ã³ã³ãã¥ãŒãã£ã³ã°ãåéããŸããã泚æã§ããŸãã ã€ãã³ããçºçãããšãå¿ èŠãªã¢ã¯ã·ã§ã³ïŒè¡12ã§ç¶æ ãæŽæ°ããããè¡15ã§ããªãªãæãïŒãå®è¡ããŠããç¶è¡ããŸãã ãã®å Žåã®æ倧ã®å©ç¹ã¯ããã®ãããªã³ãŒããç°¡åã«æ¡åŒµããŠãããè€éãªããžãã¯ãæäŸã§ããããšã§ããããšãã°ãPhil Trelfordã®èšäºãåç §ããŠãã ããã ãããã®ããããã£ãå®è£ ããå¥ã®ãªãã·ã§ã³ã¯ã FïŒãšãŒãžã§ã³ãã䜿çšããããšã§ããããã«ãããããžãã¯ãåæ§ã«å¶åŸ¡ã§ããŸãã
ã ãããä»ç§ãã¡ã¯ã³ã³ãããŒã«ãããŠããŸãããç§ãã¡ã¯å€ããéæããŸãããïŒ FïŒã«æ £ããŠããªãå Žåãäžèšã®ã³ãŒãã¯æ··ä¹±ãæãå¯èœæ§ããããŸãã äž»ãªã¢ã€ãã¢ã¯ãå¶åŸ¡ãéã«ããããšã§ãç¬èªã®æœè±¡åãç°¡åã«äœæã§ãããšããããšã§ãã ããã§æçµæ®µéã«å°éããŸã...
è€æ°ã¬ãã«ã®æœè±¡åã䜿çšãã
以åã®æçš¿ã§æžããããã«ãã©ã€ãã©ãªã¯ããã€ãã®ã¬ãã«ã®æœè±¡åãæäŸããå¿ èŠããããŸãã åã®ã¹ããããã§äœ¿çšããã²ãŒã ã®ã¿ã€ãã¯ãäœã¬ãã«ã®æœè±¡åã§ãã å®å šãªå¶åŸ¡ãæäŸããªãããè€éãªãã®ãäœæããå Žåã«åœ¹ç«ã¡ãŸãã ããããä»ã®å Žåã§ã¯ãã²ãŒã ã¯å®éã«ã¯ãæŽæ°ããšãæç»ãã®2ã€ã®æ©èœã§æ§æãããŸãã
åã®ã³ãŒããã©ã°ã¡ã³ããååŸããŠãåŒæ°ã«ããã€ãã®éšåãæœåºããã ããªã®ã§ãããã¯åé¡ãªãè¡ãããŸãã
let startGame draw update init = let game = Inverted.Game() let rec loop x = async { if game.IsRunning then let! evt = Async.AwaitObservable(game.Update, game.Draw) match evt with | Choice1Of2() -> return! loop (update x) | Choice2Of2(ctx) -> draw x ctx return! loop x } loop init
æœè±¡åstartGameã¯ãåŒæ°ãšããŠ2ã€ã®é¢æ°ãšåæç¶æ ãåããŸãã æŽæ°é¢æ°ã¯ç¶æ ãæŽæ°ããæç»é¢æ°ã¯æå®ãããDrawingContextã䜿çšããŠç¶æ ãæç»ããŸãã ãããã£ãŠãããªãªã§ã®ã²ãŒã ãããã4è¡ã§èšé²ã§ããŸãã
let mario = Image.Load("mario.png") 0 |> startGame (fun x ctx -> ctx.Draw(x, 0, mario)) (fun x -> x + 1)
æçš¿å šäœã泚ææ·±ãèªãã å Žåã次ã®ããã«å°ããããšãã§ããŸãã äžèšã§ãè€æ°ã®é¢æ°ãåãå ¥ããé«æ¬¡é¢æ°ïŒç¹ã«ç¶æ ãå ±æããŠããå ŽåïŒã¯æªè³ªãªãã¬ãŒã ã¯ãŒã¯ã§ãããšæžããŠããŸãããïŒ ã¯ããããèšããŸããïŒ ãããããã®ç¹ãæ確ã«ããŸãããã
ä»ã®ããã€ãã®é¢æ°ãé«ã¬ãã«ã®æœè±¡åãšããŠäœ¿çšãã䟿å©ãªæäœãè¡ãããšã¯éåžžã«å¯èœã§ãããããåçŽã§æ確ãªä»£æ¿æ段ãå¿ èŠã§ãã
äžèšã®4è¡ã䜿çšããŠãstartGameã®å®çŸ©ãèŠãŠãããããæ¢ã«äžã§èŠã14è¡ã®ã³ãŒãã«å€æã§ããŸãïŒã³ã¡ã³ããé€ãïŒã ã€ãŸãããã³ãããã®äžã«1ã€ïŒããŸãæ·±ããªãïŒã®ã¹ããŒãžãé 眮ããããšã§ãã³ã³ãããŒã«ãç²åŸã§ããã¯ãã§ãã ãã®æ¹æ³ã¯ãããŸãæ©èœããŠããªãã©ã€ãã©ãªã®äžã«å£ããããè¶³å Žãæ§ç¯ããããšãšã¯ç°ãªããŸããã©ã€ãã©ãªã¯ãçŸããã³ãŒããæžãããšã«é Œããªããã°ãªããªãå ŽåããããŸãã
ãªã³ã¯å¯èœãªã©ã€ãã©ãªãèšèšãã
åè¿°ããããã«ããã¬ãŒã ã¯ãŒã¯ã§ã¯ãªãã©ã€ãã©ãªãäœæããäž»ãªçç±ã®1ã€ã¯ãã©ã€ãã©ãªã®ã³ã³ãã€ã«ãåå ã§ãã ãã®ããã»ã¹ãå®å šã«å¶åŸ¡ã§ããå Žåã¯ãåé¡ã®ã©ã®éšåã解決ããããã«äœ¿çšããã©ã€ãã©ãªãéžæã§ããŸãã é£ããå ŽåããããŸãããã©ã€ãã©ãªã䜿çšããã°ãå°ãªããšããã£ã³ã¹ããããŸãã
ããŸããããã³ã°ããã©ã€ãã©ãªãäœæããããã®æ®éçãªã¬ã·ãã¯ãªããšæããŸãã 次ã®ããšã«æ³šæããããšãããããéèŠã§ãïŒã¿ã€ãã¯ãåæ§ã®ããŒã¿æ§é ãäœæããå¿ èŠãããå Žåãä»ã®ã©ã€ãã©ãªãïŒåæ§ã®ç®çã§ïŒå¿ èŠãšãããã¹ãŠã®éèŠãªæ å ±ãæäŸããå¿ èŠããããŸãã
ãã®çš®ã®è¯ãäŸã¯FsLabã§ããããã¯ãããŒã¿ãæäœããããã®å€æ°ã®FïŒããã±ãŒãžïŒ Deedle ã Math.NET Numericsãªã©ãå«ãïŒãçµã¿åãããããã±ãŒãžã§ãã FsLabããã±ãŒãžã«ã¯ãä»ã®å€ãã®ã©ã€ãã©ãªããªã³ã¯ãã1ã€ã®ã¹ã¯ãªãããä»å±ããŠããŸãïŒãœãŒã¹ã³ãŒãã¯ãã¡ã ïŒã
ãã¡ã€ã«ããã®2ã€ã®ç°¡åãªäŸã¯ããããªãã¯ã¹ãããã¬ãŒã ïŒMatrix.toFrameïŒã«ãå察æ¹åïŒFrame.toMatrixïŒã«å€æããé¢æ°ã§ãã
module Matrix = let inline toFrame matrix = matrix |> Matrix.toArray2 |> Frame.ofArray2D module Frame = let inline toMatrix frame = frame |> Frame.toArray2D |> DenseMatrix.ofArray2
Deedleãã¬ãŒã ãšMath.NETãããªãã¯ã¹ã®äž¡æ¹ã2次å é åã«ããŸãã¯ãã®éã«å€æã§ãããããããã§ã®è§£æ±ºçã¯éåžžã«ç°¡åã§ãããããã£ãŠãé åå ã®ããèŠçŽ ããå¥ã®èŠçŽ ã«ç§»åããã ãã§ãã
ããã¯éåžžã«åçŽã«èŠããŸãããç§ã¯æ¬¡ã®æ¬è³ªãèŠãŠããŸãïŒããªãã®ã©ã€ãã©ãªãäœãããŠããŠããããªãã¯ãã®ã©ã€ãã©ãªãä»ã®ãã®ãšäžç·ã«ä¿ã€ããã«ããããåªåãæãã¹ãã§ã