data Nat = Z | S Nat
例如,我们可以使用此数据类型来代表前几个数字:
Z
代表0
,S Z
代表1
,S (S Z)
代表2
,依此类推。
- 平等(即
x == y
),- 小于(即
x < y
),- 小于或等于(即
x ≤ y
),- 大于(即
x > y
),- 大于或等于(即
醇>x ≥ y
)。
1
(?) :: Nat -> Nat -> Bool
Z ? Z = True
Z ? (S n) = True
(S n) ? (S m) = n <?> m
x ? z = False
2
? :: Nat -> Nat -> Bool
(S n) ? Z = True
(S n) ? (S m) = n <?> m
x ? z = False
我不明白它与(S n)的含义以及我们应该如何区分最后的X和Z.
答案 0 :(得分:7)
这里的构造函数是
-- zero
Z
和
-- nonzero n
S n
您的第一个示例着眼于:
(?) :: Nat -> Nat -> Bool
Z ? Z = True
Z ? (S n) = True
(S n) ? (S m) = n <?> m
x ? z = False
所以,让我们去试试吧。我们可以从(==)
开始,看看它是否因任何断言而失败。
Z == Z = True -- makes sense
Z == (S n) = True -- FAIL
这不应该是真的,因为你的零不会等于任何非零值。实际上,它应该小于任何非零值!让我们试试(<)
并再次查看
Z < Z = True -- Whoops...
坚持,零并不比自己少,但是它们或等于本身。让我们测试一下(<=)
。
Z <= Z = True -- Uh huh
Z <= (S n) = True -- Yup
(S n) <= (S m) = n <= m -- S n <= S m when n <= m, makes sense!
x <= z = False -- Any other construction should be False, e.g.
-- (S n) <= Z
我会继续向您提出第二个问题,因为您希望能够更好地了解被问到的内容!
答案 1 :(得分:1)
您可以将S n
视为1 + n 和Z
为0,因此对于第一个操作,您有:
所以你可以尝试每个操作(=,&lt;,≤,&gt;,≥)来代替?并查看哪一个产生相同的结果。例如:0≥0?是;对于非负 n ,0≥1+ n ?没有;所以功能不是≥。
如果您对命令式语言更熟悉,或许将其翻译成另一种符号则具有启发性。例如,这是一个C版本:
bool operation(unsigned int a, unsigned int b) {
if (a == 0 && b == 0) {
return true;
} else if (a == 0 && b != 0) {
unsigned int n = b - 1; // Note: unused, as in original code
return true;
} else if (a != 0 && b != 0) {
unsigned int n = a - 1;
unsigned int m = b - 1;
return operation(n, m);
} else {
return false;
}
}
您的任务是确定此函数是否为所有输入返回与==
,<
,<=
,>
或>=
相同的结果。请注意,虽然我在这里使用了整数类型(unsigned int
),但实际上您的Nat
类型在Haskell中表示为链接列表。因此,除了作为学习练习之外,我不会建议过多地进行“心理翻译” - 为了忠实地表示Haskell代码实际执行的操作,需要更多的代码。