1

我试图编写一个带有不确定数量参数的操作,因此如果用户选择不填充其中一个参数,那么操作员会更改其功能。

oper
    gen_NP = overload{
        gen_NP : N -> NP =
            \noun ->
                  mkNP(noun);

        gen_NP : Str -> N -> NP =
            \mdfir, noun ->
                  mkNP(mkN(mdfir) (noun));
        ....
}

但是用这种方法编写每个新的未确定参数都会产生大量的重载。所以我用了这个方法

oper
        gen_NP : {noun : N ; mdfir : Str ; ....} -> NP =
            \obj
                case eqStr (obj.mdfir) ("") of {
                    PFalse =>
                          mkNP(mkN(mdfir) (noun));
                    PTrue =>
                          mkNP(noun);
                };

}

当我尝试第二种方法时,程序继续报告: Applying Predef.eqStr: Expected a value of type String, got VP (VGen 1 []) (LIdent(Id{rawId2utf8 = "mdfir"}))

有没有办法解决这个问题,或者有更好的方法来处理不确定数量的参数?

谢谢

4

1 回答 1

1

重载操作员的最佳实践

大量的重载是预期的做事方式。只需查看RGL 概要中的任何类别,您就可以轻松地看到单个函数名称的 20 多个重载。定义它们可能很烦人,但这是你只需要做一次的事情。然后,当您使用重载时,像这样使用它们会更好:

myRegularNoun = mkN "dog" ;
myIrregNoun = mkN "fish" "fish" ;

而不是被迫对所有事情都给出两个论点:

myRegularNoun = mkN "dog" "" ;
myIrregNoun = mkN "fish" "fish" ;

因此,拥有多个mkN实例是一项功能,而不是错误。

如何修复您的代码

我不推荐使用 Predef 函数eqStr,除非你真的知道你在做什么。对于大多数需要检查字符串的情况,可以使用标准模式匹配语法。这是修复您的功能的方法:

oper
  gen_NP : {noun : N ; mdfir : Str} -> NP = \obj ->
    case obj.mdfir of {
      "" => mkNP obj.noun ;
      _ => mkNP (mkN obj.mdfir obj.noun)
    } ;

在 GF shell 中进行测试,首先使用mdfir=""

> cc -unqual -table gen_NP {noun = mkN "dog" ; mdfir = ""}
s . NCase Nom => dog
s . NCase Gen => dog's
s . NPAcc => dog
s . NPNomPoss => dog
a . AgP3Sg Neutr

现在 mdir 中有一些非空字符串:

> cc -unqual -table gen_NP {noun = mkN "dog" ; mdfir = "hello"}
s . NCase Nom => hello dog
s . NCase Gen => hello dog's
s . NPAcc => hello dog
s . NPNomPoss => hello dog
a . AgP3Sg Neutr
于 2021-03-03T14:34:23.163 回答