using System;
public class Option {
public static Option<T> None<T>() {
return new Option<T>(default(T), present: false);
}
public static Option<T> Some<T>(T value) {
return new Option<T>(value, present: true);
}
}
public class Option<T> {
private readonly T value;
public bool Present { get; private set; }
internal Option(T value, bool present) {
this.value = value;
Present = present;
}
public T Get() {
if (!Present) {
throw new Exception("you suck");
}
return value;
}
public Option<U> Select<U>(Func<T, U> f) {
if (Present) {
return Option.Some<U>(f(value));
} else {
return Option.None<U>();
}
}
public override string ToString() {
if (Present) {
return "Some(" + value.ToString() + ")";
} else {
return "None";
}
}
}
public static class Program {
public static void Main() {
Console.WriteLine(Option.Some("hello").Select(x => x.Length));
Console.WriteLine(Option.None<string>().Select(x => x.Length));
}
}
dXNpbmcgU3lzdGVtOwoKcHVibGljIGNsYXNzIE9wdGlvbiB7CglwdWJsaWMgc3RhdGljIE9wdGlvbjxUPiBOb25lPFQ+KCkgewoJCXJldHVybiBuZXcgT3B0aW9uPFQ+KGRlZmF1bHQoVCksIHByZXNlbnQ6IGZhbHNlKTsKCX0KCglwdWJsaWMgc3RhdGljIE9wdGlvbjxUPiBTb21lPFQ+KFQgdmFsdWUpIHsKCQlyZXR1cm4gbmV3IE9wdGlvbjxUPih2YWx1ZSwgcHJlc2VudDogdHJ1ZSk7Cgl9Cn0KCnB1YmxpYyBjbGFzcyBPcHRpb248VD4gewoJcHJpdmF0ZSByZWFkb25seSBUIHZhbHVlOwoJcHVibGljIGJvb2wgUHJlc2VudCB7IGdldDsgcHJpdmF0ZSBzZXQ7IH0KCglpbnRlcm5hbCBPcHRpb24oVCB2YWx1ZSwgYm9vbCBwcmVzZW50KSB7CgkJdGhpcy52YWx1ZSA9IHZhbHVlOwoJCVByZXNlbnQgPSBwcmVzZW50OwoJfQoKCXB1YmxpYyBUIEdldCgpIHsKCQlpZiAoIVByZXNlbnQpIHsKCQkJdGhyb3cgbmV3IEV4Y2VwdGlvbigieW91IHN1Y2siKTsKCQl9CgkJcmV0dXJuIHZhbHVlOwoJfQoKCXB1YmxpYyBPcHRpb248VT4gU2VsZWN0PFU+KEZ1bmM8VCwgVT4gZikgewoJCWlmIChQcmVzZW50KSB7CgkJCXJldHVybiBPcHRpb24uU29tZTxVPihmKHZhbHVlKSk7CgkJfSBlbHNlIHsKCQkJcmV0dXJuIE9wdGlvbi5Ob25lPFU+KCk7CgkJfQoJfQoKCXB1YmxpYyBvdmVycmlkZSBzdHJpbmcgVG9TdHJpbmcoKSB7CgkJaWYgKFByZXNlbnQpIHsKCQkJcmV0dXJuICJTb21lKCIgKyB2YWx1ZS5Ub1N0cmluZygpICsgIikiOwoJCX0gZWxzZSB7CgkJCXJldHVybiAiTm9uZSI7CgkJfQoJfQp9CgpwdWJsaWMgc3RhdGljIGNsYXNzIFByb2dyYW0gewoJcHVibGljIHN0YXRpYyB2b2lkIE1haW4oKSB7CgkJQ29uc29sZS5Xcml0ZUxpbmUoT3B0aW9uLlNvbWUoImhlbGxvIikuU2VsZWN0KHggPT4geC5MZW5ndGgpKTsKCQlDb25zb2xlLldyaXRlTGluZShPcHRpb24uTm9uZTxzdHJpbmc+KCkuU2VsZWN0KHggPT4geC5MZW5ndGgpKTsKCX0KfQ==