Making Illegal States Unrepresentable
具体例
参考
恐らく初出
ぐぐったらいくつかの言語で割と引っかかるmrsekut.icon
2つのMaybeを必要とする関数で、両方ともJustである必要がある関数の場合は、
2つのMaybeを取るのではなく、Maybe (a, b)を取るように修正する
長さの同じ2つのListを取ることを強制するためには、[(a, b)]を取るように変えればいい
型の取りうるパターンの数に着目して、隙がないように作ってる
ときには妥協も必要
2つの例で書かれている
emailのverifiedとunverifiedという2つの状態をBooleanで区別するのではなくUnionで書こうな、という話
EmailとAddressのどちらかが必須である、ということを表すために
Maybeとかを使うと、不適切な状態で作られうるので、これもUnionでやろうな、という話
UnvalidateedAddressとValidatedAddressのような型で区別した際に、何かの検査の後に達する状態の方(ValidatedAddress)はprivateにしておくと良い
たしかにmrsekut.icon
UnvalidateedAddressの方は公開していても問題なさそうmrsekut.icon
オセロの実装で考える
15パターンの時
連絡先には、電子メール、住所、自宅の電話、または勤務先の電話のうち少なくとも 1 つが必要
code:after.fs
type Contact =
{
Name: PersonalName;
PrimaryContactMethod: ContactMethod;
SecondaryContactMethods: ContactMethod list;
}
type ContactMethod =
| Email of EmailContactInfo
| PostalAddress of PostalContactInfo
| HomePhone of PhoneContactInfo
| WorkPhone of PhoneContactInfo
PrimaryContactMethod: ContactMethod
SecondaryContactMethods: ContactMethod list;
とすることで、Primaryの方は必須で、Secondaryの方はoptional(空リスト)とできる
これでもちょっと問題ありそうではあるmrsekut.icon
PrimaryとSecondaryに同じ物が入りうる
Secondary内に重複がありうる
妥協点としては良さそうな気はするmrsekut.icon