这是我从 YAHT 锻炼的解决方案:
练习 4.6 编写一个数据类型 Tuple,它可以包含一个、两个、三个或四个元素,具体取决于构造函数(也就是说,应该有四个构造函数,每个参数数量一个)。还提供函数 tuple1 到 tuple4 ,它们接受一个元组并返回该位置的值,或者如果数字有效则返回 Nothing(即,您要求元组上的 tuple4 只包含两个元素)。
当我写第一行时,我对与 C# 相比的简单性感到兴奋
数据元组 abcd = Tuple1 a | 元组2 ab | 元组3 abc | 元组4 abcd
-- 类 Tuplex<a,b,c,d> {
-- Tuplex(a p1){ _p1 = p1; }
-- Tuplex(a p1, b p2){ _p1 = p1; _p2 = p2; }
-- Tuplex(a p1, b p2, c p3){ _p1 = p1; _p2 = p2; _p3 = p3; }
-- Tuplex(a p1, b p2, c p3, d p4){ _p1 = p1; _p2 = p2; _p3 = p3; _p4 = p4; }
-- 公共 Nullable<a> _p1;
-- 公共 Nullable<b> _p2;
-- 公共 Nullable<c> _p3;
-- 公共 Nullable<d> _p4;
-- }
在 C# 中,我可以毫无问题地访问任何字段,但在这里我应该编写一个“访问器函数”,对吧?这里的代码量让我很难过。
我可以在这里有更短的代码吗?
tuple1 ∷ 元组 abcd → 可能 a
tuple2 ∷ 元组 abcd → 也许 b
tuple3 ∷ 元组 abcd → 可能 c
tuple4 ∷ 元组 abcd → 可能 d
tuple1 (Tuple1 a) = 只是一个
tuple1 (Tuple2 ab) = 只是一个
tuple1 (Tuple3 abc) = 只是一个
tuple1 (Tuple4 abcd) = 只是一个
tuple2 (Tuple1 a) = 无
tuple2 (Tuple2 ab) = 只是 b
tuple2 (Tuple3 abc) = 只是 b
tuple2 (Tuple4 abcd) = 只是 b
tuple3 (Tuple1 a) = 没有
tuple3 (Tuple2 ab) = 没有
tuple3 (Tuple3 abc) = 只是 c
tuple3 (Tuple4 abcd) = 只是 c
tuple4 (Tuple1 a) = 无
tuple4 (Tuple2 ab) = 没有
tuple4 (Tuple3 abc) = 没有
tuple4 (Tuple4 abcd) = Just d
-- 单元测试
prop_tx1 = tuple1 (Tuple1 4) ≡ 仅 4
prop_tx2 = tuple1 (Tuple2 4 'q') ≡ 只有 4
prop_tx3 = tuple2 (Tuple1 4) ≡ (Nothing ∷ Maybe Char)
prop_tx4 = tuple2 (Tuple2 4 'q') ≡ Just 'q'