0

我从一个这样开始的函数中提取了以下行(教科书示例不完整):

    let rec unify (exp1:exp) (exp2:exp) (k:(subst -> subst)) (sub:subst) =
            match checkmap exp1 sub,checkmap exp2 sub with                                          
                | Var a,Var b when a = b -> k sub                                                   
                | Var a,Var b -> k (safeInput<|||((safeInput<|||(sub,a,Var(b))),b,Var(a)))

线:

    Var a,Var b -> k (safeInput<|||((safeInput<|||(sub,a,Var(b))),b,Var(a)))

safeInput 引用“安全地”将类型输入到 Map 结构中......我只是想知道这里的操作员实际上在做什么?另外,是否有更直观的方式来构建上述行?

4

2 回答 2

2

如果你输入

(<|||);;

进入 F# Interactive,你会得到它的签名:

val it : (('a -> 'b -> 'c -> 'd) -> 'a * 'b * 'c -> 'd) = <fun:it@1>

它的定义类似于

let inline (<|||) f (a, b, c) = f a b c

所以最后一个表达式可以重写为

k (safeInput (safeInput sub a (Var b)) b (Var a))

要改进该功能,您还可以:

  • 创建 let 绑定以保存立即值
  • 重用exp1exp2创建相同的值

例如

let rec unify (exp1 : exp) (exp2 : exp) (k : subst -> subst) (sub : subst) =
    match checkmap exp1 sub,checkmap exp2 sub with
    | Var a, Var b when a = b -> k sub
    | Var a, Var b -> 
        let sub' = safeInput sub a exp2
        k (safeInput sub' b exp1)
于 2013-10-10T15:56:53.633 回答
1

运算符只需将<|||右侧的参数(以元组形式提供)传递给左侧的函数,因此该行的含义与以下内容相同:

k (safeInput (safeInput sub a (Var b)) b (Var a))

或者,如果您想将该行分成两部分以使其更具可读性:

let sub' = safeInput sub a (Var b)
k (safeInput sub' b (Var a))

我不知道使用它的书,但我想这个想法是添加从变量'a'到变量'b'的映射以及从变量'b'到变量'a'的另一个映射。

于 2013-10-10T15:56:02.587 回答