在Haskell中,接受以下bind定义:
type RState s a = s -> (a, s)
bind :: RState s a -> (a -> RState s b) -> RState s b
bind sf f = \s ->
let (a, s'') = sf s'
(b, s') = f a s
in (b, s'')
如何获得Coq接受的类似定义? 我的尝试是:
Definition RState (S A : Type) : Type := S -> A * S.
Definition bind (S A B : Type) (sf : RState S A) (f : A -> RState S B) : RState S B :=
fun s =>
let (a, s'') := sf s' in
let (b, s') := f a s in
(b, s'').
但它失败并显示以下错误消息:
Error: The reference s' was not found in the current environment.
答案 0 :(得分:0)
假设g :: s -> s
。考虑
sf :: RState s s
sf = get = \s -> (s, s)
f :: s -> RState s s
f = put . g = \a _ -> ((), g a)
我们得到:
bind sf f = \s ->
let (a, s'') = sf s'
(b, s') = f a s
in (b, s'')
= \s ->
let (a, s'') = (s', s')
(b, s') = ((), g a)
in (b, s'')
= \s ->
let (b, s') = ((), g s')
in (b, s')
= \s ->
let s' = g s' in ((), s')
这涉及计算g
的固定点,由于可能缺少终止,因此在Coq中通常是不可能的。
正如David Young在上面提到的那样,如果像bind
这样的东西在Coq中是可行的,那么必须通过证明这个递归终止的证明条件来增强它。这种改进并非易事。
答案 1 :(得分:0)
bind
需要证明函数实际将返回。如果您添加具有此效果类型的参数H
取决于实际的sf
,f
和s
值,则可以提取所需的{{1}来自“认证”字词(b, s'')
的对。
请注意如何实际计算 H
和sf
函数必须在f
的构造中解释,特定H
},sf
和f
。
(可能有其他/更好的方法来实现这一点。希望其他人可以添加到此主题。)
s