ãåããããªswitchæããã¡ãã¡ã«ããã¨æ¹ä¿®ãå°é£ãã£ã¦æ¬å½ï¼(Expression Problem)
æ¦è¦
ããã°ã©ã ã®è¨è¨ã§ã¯ããããåããããªswitchæããã¡ãã¡ã«ããã¨æ¹ä¿®ãå°é£ã«ãªããã¨è¨ããã¦ãã¾ãããããã£ãå ´åã¯ããswitchã®åå²ãããªãã¸ã§ã¯ãã®å¤æ æ§ãå©ç¨ãã¦ç¡ããã¹ãã ãã¨ãè¨ããã¾ãã
ããããããã¯æ¬å½ã§ãããããããã¹ã¦ã®åå²ãè¨è¿°ãããåã«æ¶ãå»ããããããããªæ¥µè«ã¯è¨±ãããã®ã§ãããããä»åã¯ããã«ã¤ãã¦èå¯ãã¾ãã
ç¨èª
-
åå²æ¡ä»¶
- åæãããå ´ååãã®ç¨®é¡ããããã¯ãã®ä¸è¦§ã
- ã±ã¼ã¹ããã¼ã¿åã¨ãå¼ã¶ã
å¦çã®ç¨®é¡
- å ´ååãã«å¯¾å¿ãããç¹å®ã®å ´åã«å®è¡ããå¦çã
- é¢æ°ãã¡ã½ããã¨ãå¼ã¶ã
ä¸è¶³é£ã³ã®çµè«
æ¡ä»¶ç¯ã«ããåå²ã¯ãåå²ãã©ãã«å±ããããåå¥ã«æ±ºãããã¾ãããåå²æ¡ä»¶ã®å¢æ¸ã«ããå½±é¿ã大ãããªããã¡ã§ããã§ãããå¦çã®ç¨®é¡ãå¢æ¸ããå ´åã¯ãæ¹ä¿®ã¯å®¹æã§ãã
- switchæã使ãå ´å
- 代æ°çãã¼ã¿åã®ãã¿ã¼ã³ãããã使ç¨ããå ´åã
å¤æ æ§ãå©ç¨ããåå²ã®äºå決å®ã¯ããã¹ã¦ã®åå²ã«ã¤ãã¦ä¸ç®æã§å¤å®ããå¿ è¦ãããã¾ãããããã®æ¡ä»¶ã®å ´åã®å ¨ã¦ã®å¦çãã¨ããå½¢ã§è¨è¿°ãã¾ã¨ã¾ã£ã¦ãããããåå²æ¡ä»¶ã®å¢æ¸ã«ã¯å¯¾å¿ããããã§ããããããå¦çã®ç¨®é¡ãå¢æ¸ããå ´åã¯ãåå²ã®å ¨ã±ã¼ã¹ã«ã¤ãã¦æ¹ä¿®ãè¡ãå¿ è¦ãããã¾ãã
- ã¯ã©ã¹ã®ç¶æ¿ã使ãå ´åã
- ã¡ã½ããéåã¨ãã¦ã®ãªãã¸ã§ã¯ã(ã¬ã³ã¼ã)ãåçã«çæããå ´åã
- 2.ãããã¾ãåå²æ¡ä»¶ã¨å¦çã®ç¨®é¡ã®ã©ã¡ããå¤æ´ããããããã¢ã¸ã¥ã¼ã«ã¨ãã¦åå²ãã©ãã«å±ããã¹ãããèæ ®ãã¦é¸æããã¹ãã§ãã
ããããããããããã«ãããã§ã®è©±é¡ã¯Expression Problemã§ãã1. 2.ã®ã©ã¡ããã§ãããããã®ç´ æ´ãªæ¹æ³ã§ã¯ããã¼ã¿å(åå²æ¡ä»¶)ã®è¿½å ã¨é¢æ°(å¦çã®ç¨®é¡)ã®è¿½å ã®ä¸¡æ¹ã容æã«(åã³ã³ãã¤ã«ç¡ãã«)ãé£ãã¨ãããã¨ããããã¾ãã
ç´ æ´ãªæ¹æ³ã§ã¯ãªã解決ã¨ã¯ãä¾ãã°åã¯ã©ã¹ããå¤ç¸ã´ã¡ãªã¢ã³ããå¤ç¸ã¬ã³ã¼ããå©ç¨ããæ¹æ³ãããããã§ãããããã§ã¯åãæ±ãã¾ããã
ç¶ãã¯å ·ä½ä¾ã§ãã
åé¡
次ã®ããã°ã©ã ã§ã¯ãåä¾ã»å¤§äººç·æ§ã»å¤§äººå¥³æ§ã»è人ã®4ãã¿ã¼ã³ã«ã¤ãã¦ãæéã表示ãã¦ãã¾ãã大人女æ§ã®å ´åãæ°´ææ¥ã¯ã¬ãã£ã¼ã¹ãã¼ã¨ãã¦ç¹å¥æéã«å¤æ´ããã¾ãã
ããããªãã¡ã¯ã¿ãªã³ã°ãã¦ãå¾ã ã®æ¹ä¿®ã容æã¨ãªãããã«ãã¾ããããè¨èªã¯C#ã¨ãã¾ãã
using System; namespace CalcPrice { public enum PriceFlag { Children, Gentlemen, Lady, Old } public class Price { public const decimal ChildrenPrice = 500; public const decimal AdultPrice = 2000; public const decimal LadiesDayPrice = 1500; public const decimal OldPrice = 1000; public const DayOfWeek LadiesDay = DayOfWeek.Wednesday; public PriceFlag Flag { private set; get; } public Price(PriceFlag flag) { this.Flag = flag; } } public static class Program { static void Main(string[] args) { var today = new DateTime(2015, 1, 7);// æ°´ææ¥ // 顧客ã¨ãã¦ãåä¾ãç·æ§ã女æ§ãè人ãä¸äººãã¤æ¥ãã¨ããã var customers = new[]{ new Price(PriceFlag.Children), new Price(PriceFlag.Gentlemen), new Price(PriceFlag.Lady), new Price(PriceFlag.Old) }; // æé表示 var i = 1; foreach (var c in customers) { Console.WriteLine(i + ":"); switch (c.Flag) { case PriceFlag.Children: Console.WriteLine("åä¾æéã¯" + Price.ChildrenPrice + "åã§ã"); break; case PriceFlag.Gentlemen: Console.WriteLine("大人æéã¯" + Price.AdultPrice + "åã§ã"); break; case PriceFlag.Lady: if (today.DayOfWeek == Price.LadiesDay) { Console.WriteLine("ã¬ãã£ã¼ã¹ãã¼æéã¯" + Price.LadiesDayPrice + "åã§ã"); } else { Console.WriteLine("大人æéã¯" + Price.AdultPrice + "åã§ã"); } break; case PriceFlag.Old: Console.WriteLine("ã·ãã¢æéã¯" + Price.OldPrice + "åã§ã"); break; default: throw new Exception("invalid PriceFlag"); } i++; } // åè¨æéè¨ç® decimal sum = 0; foreach (var c in customers) { switch (c.Flag) { case PriceFlag.Children: sum += Price.ChildrenPrice; break; case PriceFlag.Gentlemen: sum += Price.AdultPrice; break; case PriceFlag.Lady: if (today.DayOfWeek == Price.LadiesDay) { sum += Price.LadiesDayPrice; } else { sum += Price.AdultPrice; } break; case PriceFlag.Old: sum += Price.OldPrice; break; default: throw new Exception("invalid PriceFlag"); } } Console.WriteLine("åè¨ : " + sum + "å"); Console.ReadKey(); } } }
åºåã¯ä»¥ä¸ã¨ãªã£ã¦ãã¾ãã
1: åä¾æéã¯500åã§ã 2: 大人æéã¯2000åã§ã 3: ã¬ãã£ã¼ã¹ãã¼æéã¯1500åã§ã 4: ã·ãã¢æéã¯1000åã§ã åè¨ : 5000å
åç1 åå²ã¯åå²å¯¾è±¡èªèº«ã«è¡ããã
Mainé¢æ°ã«switchæã2åãåºã¦ãã¦ãã¦èªã¿ã¥ããã®ã§ãPriceã¯ã©ã¹ã«æ¼ãè¾¼ãããã¨ã«ãã¾ããã
// Price, Programã¯ã©ã¹ã®ã¿å¤æ´ public class Price { private const decimal ChildrenPrice = 500; private const decimal AdultPrice = 2000; private const decimal LadiesDayPrice = 1500; private const decimal OldPrice = 1000; private const DayOfWeek LadiesDay = DayOfWeek.Wednesday; public PriceFlag Flag { private set; get; } public string GetName(DayOfWeek dayOfWeek) { switch (this.Flag) { case PriceFlag.Children: return "åä¾æé"; case PriceFlag.Gentlemen: return "大人æé"; case PriceFlag.Lady: if (dayOfWeek == LadiesDay) { return "ã¬ãã£ã¼ã¹ãã¼æé"; } return "大人æé"; case PriceFlag.Old: return "ã·ãã¢æé"; default: throw new Exception("invalid PriceFlag"); } } public decimal Calculate(DayOfWeek dayOfWeek) { switch (this.Flag) { case PriceFlag.Children: return ChildrenPrice; case PriceFlag.Gentlemen: return AdultPrice; case PriceFlag.Lady: if (dayOfWeek == LadiesDay) { return LadiesDayPrice; } return AdultPrice; case PriceFlag.Old: return OldPrice; default: throw new Exception("invalid PriceFlag"); } } public Price(PriceFlag flag) { this.Flag = flag; } } public static class Program { static void Main(string[] args) { var today = new DateTime(2015, 1, 7);// æ°´ææ¥ // 顧客ã¨ãã¦ãåä¾ãç·æ§ã女æ§ãè人ãä¸äººãã¤æ¥ãã¨ããã var customers = new[]{ new Price(PriceFlag.Children), new Price(PriceFlag.Gentlemen), new Price(PriceFlag.Lady), new Price(PriceFlag.Old) }; // æé表示 var i = 1; foreach (var c in customers) { Console.WriteLine(i + ":"); Console.WriteLine(c.GetName(today.DayOfWeek) + "ã¯" + c.Calculate(today.DayOfWeek) + "åã§ã"); i++; } // åè¨æéè¨ç® decimal sum = 0; foreach (var c in customers) { sum += c.Calculate(today.DayOfWeek); } Console.WriteLine("åè¨ : " + sum + "å"); Console.ReadKey(); } }
åå²ãå¤å°æ±ãã§ãããå ã»ã©ããã¯è¯ãããã«è¦ãã¾ãã
åç2 åå²ã¯ãªãã¸ã§ã¯ãæåçã«ã¯ã©ã¹ç¶æ¿ã§å®è£ ãã
switchæã«ããåå²ã¯ãããããªãã¸ã§ã¯ãæåçã§ã¯ããã¾ãããå®è¡ããã¾ã§ãã¹ã¦ã®ã±ã¼ã¹ãæ£ããå®è£ ããã¦ããããããã¾ããããã¡ã½ãããå¢ããããã®é½åº¦switchæãå é¨ã«å¢ãã¦ãããã¨ã«ãªãã¾ãããã£ã¦ãPriceãæ½è±¡ã¯ã©ã¹ã¨ãããã®å®ä½ã¨ãã¦åä¾æéã»ç·æ§æéã»å¥³æ§æéã»ã·ãã¢æéã®ããããããµãã¯ã©ã¹ã¨ãã¦å®è£ ãããã¨ã«ãã¾ãã
// Price, Programã¯ã©ã¹ã®ã¿å¤æ´ public abstract class Price { public abstract PriceFlag Flag { get; } public abstract string GetName(DayOfWeek dayOfWeek); public abstract decimal Calculate(DayOfWeek dayOfWeek); public static Price Create(PriceFlag flag) { switch (flag) { case PriceFlag.Children: return new ChildrenPrice(); case PriceFlag.Gentlemen: return new GentlemenPrice(); case PriceFlag.Lady: return new LadyPrice(); case PriceFlag.Old: return new OldPrice(); default: throw new Exception("invalid PriceFlag"); } } } public class ChildrenPrice : Price { public override PriceFlag Flag { get { return PriceFlag.Children; } } public override string GetName(DayOfWeek dayOfWeek) { return "åä¾æé"; } public override decimal Calculate(DayOfWeek dayOfWeek) { return 500; } } public class GentlemenPrice : Price { public override PriceFlag Flag { get { return PriceFlag.Gentlemen; } } public override string GetName(DayOfWeek dayOfWeek) { return "大人æé"; } public override decimal Calculate(DayOfWeek dayOfWeek) { return 2000; } } public class LadyPrice : Price { private const DayOfWeek LadiesDay = DayOfWeek.Wednesday; public override PriceFlag Flag { get { return PriceFlag.Lady; } } public override string GetName(DayOfWeek dayOfWeek) { if (dayOfWeek == LadiesDay) { return "ã¬ãã£ã¼ã¹ãã¼æé"; } return "大人æé"; } public override decimal Calculate(DayOfWeek dayOfWeek) { if (dayOfWeek == LadiesDay) { return 1500; } return 2000; } } public class OldPrice : Price { public override PriceFlag Flag { get { return PriceFlag.Old; } } public override string GetName(DayOfWeek dayOfWeek) { return "ã·ãã¢æé"; } public override decimal Calculate(DayOfWeek dayOfWeek) { return 1000; } } public static class Program { static void Main(string[] args) { var today = new DateTime(2015, 1, 7);// æ°´ææ¥ // 顧客ã¨ãã¦ãåä¾ãç·æ§ã女æ§ãè人ãä¸äººãã¤æ¥ãã¨ããã var customers = new[]{ Price.Create(PriceFlag.Children), Price.Create(PriceFlag.Gentlemen), Price.Create(PriceFlag.Lady), Price.Create(PriceFlag.Old) }; // 以ä¸åæ§ã®ããçç¥ } }
ã¯ã©ã¹å®ç¾©ãå¢ãã¦ãããããããããã¾ãããæ¡ä»¶åå²ã¯ãã£ãããã¾ãããPriceFlagã¯ä½¿ç¨ããã¦ããªãã®ã§æ¹æ¶ãã¦ãè¯ãããã§ãããä»ã®ã¨ããæ®ãã¦ãããã¨ã«ãã¾ãã
é¢æ°åããã°ã©ãã³ã°è¨èªãªããã¹ã¦ã解決ãã¦ãããï¼
åç1, 2ã®ããããã®ãã¿ã¼ã³ãF#ã§é¢æ°åããã°ã©ãã³ã°é¢¨ã«æ¸ãã¦ã¿ã¾ãããã
åç1' Priceåã®ã¡ã½ããã¨ãã¦ãã¿ã¼ã³ããããã
Priceåã¯ã代æ°çãã¼ã¿å(ã©ãã«ä»ãã´ã¡ãªã¢ã³ããå¤å¥å ±ç¨ä½)ã§å®è£ ããã®ãèªç¶ã§ãããã ã¡ã½ããã¨ãã¦GetNameã¨Caluclateãå®è£ ããå é¨ã§switchçãªãã¿ã¼ã³ãããããã¦ããã¾ãã
namespace CalcPrice open System type Price = Children | Gentlemen | Lady | Old with member this.GetName dayOfWeek = match this with | Children -> "åä¾æé" | Gentlemen -> "大人æé" | Lady -> match dayOfWeek with | DayOfWeek.Wednesday -> "ã¬ãã£ã¼ã¹ãã¼æé" | _ -> "大人æé" | Old -> "ã·ãã¢æé" member this.Calculate dayOfWeek = match this with | Children -> 500m | Gentlemen -> 2000m | Lady -> match dayOfWeek with | DayOfWeek.Wednesday -> 1500m | _ -> 2000m | Old -> 1000m end module Program = [<EntryPoint>] let main args = let today = new DateTime(2015, 1, 7)// æ°´ææ¥ // 顧客ã¨ãã¦ãåä¾ãç·æ§ã女æ§ãè人ãä¸äººãã¤æ¥ãã¨ããã let customers = [Children; Gentlemen; Lady; Old] // æé表示 customers |> List.iteri (fun (i:int) (c:Price) -> printfn "%d:" (i + 1); printfn "%sã¯%Måã§ã" (c.GetName today.DayOfWeek) (c.Calculate today.DayOfWeek) ) // åè¨æéè¨ç® let sum = customers |> List.sumBy (fun c -> c.Calculate today.DayOfWeek) printfn "åè¨ : %Må" sum; Console.ReadKey() |> ignore; 0
åç2' åçã«ãªãã¸ã§ã¯ããçæãã¦å®è£ ãã
åã«ã¯ã©ã¹ç¶æ¿ãåç¾ããã ããªãF#ã§ãC#ã¨ã»ã¼*1åãããã«ã§ãã¾ãããåãã«ãã¦ãé¢ç½ã¿ãç¡ãã®ã§ãããã§ã¯ã¬ã³ã¼ãã§å®ç¾ãã¦ã¿ã¾ãã
namespace CalcPrice open System type Price = { GetName:DayOfWeek->string; Calculate:DayOfWeek->decimal } [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>] module Price = let children () = { GetName = (fun dayOfWeek -> "åä¾æé"); Calculate = (fun dayOfWeek -> 500m) } let gentlemen () = { GetName = (fun dayOfWeek -> "大人æé"); Calculate = (fun dayOfWeek -> 2000m) } let lady () = { GetName = (fun dayOfWeek -> match dayOfWeek with | DayOfWeek.Wednesday -> "ã¬ãã£ã¼ã¹ãã¼æé" | _ -> "大人æé"); Calculate = (fun dayOfWeek -> match dayOfWeek with | DayOfWeek.Wednesday -> 1500m | _ -> 2000m) } let old () = { GetName = (fun dayOfWeek -> "ã·ãã¢æé"); Calculate = (fun dayOfWeek -> 1000m) } module Program = [<EntryPoint>] let main args = let today = new DateTime(2015, 1, 7)// æ°´ææ¥ // 顧客ã¨ãã¦ãåä¾ãç·æ§ã女æ§ãè人ãä¸äººãã¤æ¥ãã¨ããã let customers = [Price.children (); Price.gentlemen (); Price.lady (); Price.old ()] // 以ä¸åæ§ã®ããçç¥
ä¸é¢¨å¤ãã£ãå½¢ã§ã¯ããã¾ãããå ´ååãã±ã¼ã¹ãã¨ã®ãªãã¸ã§ã¯ããä½ããã¦ãã¾ãã
é¢æ°åããã°ã©ãã³ã°ã¯å ¨ã¦ã解決ãã¦ãããï¼
確ãã«è¨è¿°éã¯å¤§å¹ ã«æ¸ãããã¿ã¼ã³ãããçã®å¼·åãªè¨èªæ©è½ãå©ç¨ãããã¨ã§ãããå®å ¨ã§æ確ãªè¨è¿°ãå¯è½ã«ãªã£ãããã«è¦ãã¾ãã *2
ããããªãããããã«ã¯æ¬è³ªçãªåé¡ã¨ãã¦ãæ¹ä¿®ã®å®¹æããæªã æ®ããã¦ãã¾ãã
Expression Problem
Expression Problemã¨ã¯ã大ã¾ãã«è¨ãã°ããã¼ã¿å(åå²æ¡ä»¶)ã®è¿½å ã¨é¢æ°(å¦çã®ç¨®é¡)ã®è¿½å ã®ä¸¡æ¹ã容æã«(åã³ã³ãã¤ã«ç¡ãã«)è¡ãããã©ããããããã°ã©ãã³ã°è¨èªã®è¡¨ç¾è½åã®ã²ã¨ã¤ã®ææ¨ã§ãããã¨ãããããªè©±é¡ã§ãã
ããã§æããä¾ã§è¨ããªããä¾ãã°
- ãã¼ã¿å(åå²æ¡ä»¶)ã®è¿½å = åä¾æé(Children)ããå¦çæé(Student)ã¨å°å¦çæªæºæé(Infant)ã«åå²ãã
- é¢æ°(å¦çã®ç¨®é¡)ã®è¿½å = æé種å¥å(GetName)ã¨æéè¨ç®(Calculate)以å¤ã«ãæ¥å ´ç¹å ¸å¤å®(GetFavor)ã®å¦çã追å ãã
ã¨ãã£ããã®ãèãããããã§ãã
åç1, 1'ã®å ´å(switchæããã¿ã¼ã³ããã)
switchæã使ã£ããã代æ°çãã¼ã¿åã®ãã¿ã¼ã³ãããã使ç¨ããå ´åã次ã®ãã¨ãè¨ãããã§ãã
- ãã¼ã¿å(åå²æ¡ä»¶)ã®è¿½å
- å°é£ã§ããå
¨ã¦ã®å¦ç(GetNameãCaluclateã¡ã½ãã)ã«æ¹ä¿®ãè¡ãå¿
è¦ãããã¾ãã
- ã¾ãããã¯ç¹ã«ãåå²ãåå®ç¾©ããé¢ããå¤é¨ã®å ´æã§ä½¿ç¨ããã¦ããã¨ãé¡èã«ãªãã¾ãã
- å°é£ã§ããå
¨ã¦ã®å¦ç(GetNameãCaluclateã¡ã½ãã)ã«æ¹ä¿®ãè¡ãå¿
è¦ãããã¾ãã
- é¢æ°(å¦çã®ç¨®é¡)ã®è¿½å
- 容æã§ããæ¢åã®å¦çã«ã¯æãå ãããã¨ãªããæ°ããã¡ã½ããã追å ã§ãã¾ãã
- åå®ç¾©ããé¢ããå ´æã§ãåé¡ãªãæ°ããªåå²å¦çã追å ã§ããã§ãããã
åç2, 2'ã®å ´å(å¤æ ãåçãªãã¸ã§ã¯ãçæ)
ã¯ã©ã¹ã®ç¶æ¿ããåçã«ãªãã¸ã§ã¯ããçæããå ´åã次ã®ãã¨ãè¨ãããã§ãã
- ãã¼ã¿å(åå²æ¡ä»¶)ã®è¿½å
- 容æã§ããæ¢åã®ãã¼ã¿å(Gentlemen, Lady, Old)ã«æãå ãããã¨ãªããæ°ããªãã¼ã¿å(Student, Infant)ã追å ã§ãã¾ãã
- é¢æ°(å¦çã®ç¨®é¡)ã®è¿½å
- å°é£ã§ããå ¨ã¦ã®ãã¼ã¿å(Children, Gentlemen, Lady, Old)ã«æ¹ä¿®ãè¡ããããããã«æ°ããã¡ã½ãã(GetFavor)ã追å ããå¿ è¦ãããã¾ãã
çµè«
åé ã®çµè«ã®ç¹°ãè¿ãã«ãªãã¾ããã
- ãã¼ã¿å(åå²æ¡ä»¶)ã®è¿½å ã¨ãé¢æ°(å¦çã®ç¨®é¡)ã®è¿½å ã®ä¸¡æ¹ã容æã«ãã解ã¯ãä»åæ示ããç´ æ´ãªå®è£ ã«ã¯ç¡ãããã§ãã
- ãswitchã®åå²ããªãã¸ã§ã¯ãã®å¤æ ã§ç½®ãæããã¹ãã ãã¨ããè¨æã¯å¿ ãããçã§ã¯ãªããåç1, 1'ã¨åç2, 2'ã®ãã¿ã¼ã³ãé©å®ä½¿ãåããã¹ãã§ãã
- ãã®éã®åºæºã¨ãã¦ã¯ã以ä¸ãèãããã¾ãã
- åå²æ¡ä»¶ã¨å¦çã®ç¨®é¡ã©ã¡ãã«å¤æ´ãããããã
- åå²ãåã®å©ç¨å´ã§ãè¡ãå¿ è¦ãããã®ã(åç1, 1'ã®ãã¿ã¼ã³)ãããã¨ãåå²ãåã®æä¾å´ã§ã®ã¿è¡ãããã®ã(åç2, 2'ã®ãã¿ã¼ã³)
é·ããªãã¾ããããä»åã¯ä»¥ä¸ã§ãã
*1:protectedãç¡ããªã©ã®ãããå®å ¨ã§ã¯ããã¾ãã
*2:ããã¯åã«è¨èªæ©è½ã«ãããã®ã§ãããé¢æ°åããã°ã©ãã³ã°ã®ã¹ã¿ã¤ã«ã¨ã¯ãã»ã©é¢ä¿ãç¡ãããã§ã
*3:ã¯ã©ã¹ç¶æ¿ãå©ç¨ããå ´åãåå®ç¾©ããé¢ããå¤é¨ã®å ´æã§åå²ãè¡ããã¨ã¯ãåçåå¤æ(ãã¦ã³ãã£ã¹ã)ãããªãéãä¸å¯è½ã§ãã