−using System;
using System.Collections.Generic;
using System.Linq;
IExpr rule = new Or(new HasTag("article"), new And(new HasTag("video"), new HasTag("captioned")));
foreach (var tags in new[]
{
new HashSet<string> { "article" },
new HashSet<string> { "video" },
new HashSet<string> { "video", "captioned" }
}) Console.WriteLine(rule.Eval(tags));
interface IExpr { bool Eval(IReadOnlySet<string> tags); }
sealed record HasTag(string Tag) : IExpr
{
public bool Eval(IReadOnlySet<string> tags) => tags.Contains(Tag);
}
sealed record And(IExpr Left, IExpr Right) : IExpr
{
public bool Eval(IReadOnlySet<string> tags) => Left.Eval(tags) && Right.Eval(tags);
}
sealed record Or(IExpr Left, IExpr Right) : IExpr
{
public bool Eval(IReadOnlySet<string> tags) => Left.Eval(tags) || Right.Eval(tags);
}
+using System;
using System.Collections.Generic;
using System.Linq;
IExpr rule = new Or(new HasTag("article"), new And(new HasTag("video"), new HasTag("captioned")));
foreach (var tags in new[]
{
new HashSet<string> { "article" },
new HashSet<string> { "video" },
new HashSet<string> { "video", "captioned" }
}) Console.WriteLine(rule.Eval(tags));
// 조건의 종류가 달라도 같은 입력으로 참·거짓을 계산하게 한다.
interface IExpr { bool Eval(IReadOnlySet<string> tags); }
sealed record HasTag(string Tag) : IExpr
{
public bool Eval(IReadOnlySet<string> tags) => tags.Contains(Tag);
}
// 하위 식의 계산에 위임해 조합 규칙만 담당한다.
sealed record And(IExpr Left, IExpr Right) : IExpr
{
public bool Eval(IReadOnlySet<string> tags) => Left.Eval(tags) && Right.Eval(tags);
}
sealed record Or(IExpr Left, IExpr Right) : IExpr
{
public bool Eval(IReadOnlySet<string> tags) => Left.Eval(tags) || Right.Eval(tags);
}