【问题标题】:ocaml problems with nested functions and variables嵌套函数和变量的 ocaml 问题
【发布时间】:2018-05-15 23:35:46
【问题描述】:

我正在尝试根据具有值 [value] 的列来限制表的值的函数 retric。我的想法是为满足条件列和值参数的列制作一个由真假组成的列表。稍后递归匹配将选择列,listmaker 函数将根据真假列表创建一个新列。

当谈到存储在 ocaml 嵌套变量中时,让...在范围界定中我很困惑。下面的代码有什么问题?

let rec restrict (column, value, aTable) = match aTable with
    name,[]->[]
  |name,(col,vals)::rest->if col=column
      then (col,auxListMaker(vals,trueFalseList))::restrict (column,value.(name,rest))
      else restrict (column,value.(name,rest))

let rec auxTrueFalser (column, value, aTable) = match aTable with 
    name,[]->[]
  |name,(col,vals)::rest-> if column=col 
      then (if List.hd vals = value 
            then true::aux1(column,value,(name,[(col,List.tl vals)]))
            else false::aux1(column,value,(name,[(col,List.tl vals)])))
      else aux1(column,value,(name,rest)) 
in 

let trueFalseList =  auxTrueFalser (column, value, aTable) in

let rec auxListMaker (vals, trueFalseList) = match vals with
    []->[]
  |h::t -> if List.hd trueFalseList
      then h::auxListMaker(t,List.tl trueFalseList)
      else auxListMaker(t,List.tl trueFalseList)
in

【问题讨论】:

    标签: syntax-error ocaml


    【解决方案1】:

    主要要认识到let 有两种用途。第一种形式用于定义模块中的值,并且必须出现在模块的最外层。它看起来像这样:

    let name = expression
    

    作为一种方便的语法,您可以像这样在最外层定义一个函数:

    let name arg = expression
    

    let 的另一种形式可以出现在任何地方,用于定义局部变量。它看起来像这样:

    let name = expression1 in expression2
    

    这将name 建立为具有expression1 给定值的局部变量。名称的范围(可以使用的地方)是expression2

    同样,作为一种方便的语法,您可以像这样定义一个本地函数:

    let name arg = expression1 in expression2
    

    在我看来 auxListMakerauxTrueFlser 应该是在 restrict 中定义的本地函数。 trueFalseList 应该是一个本地(非函数)值。所以restrict 的形式应该是这样的:

    let rec restrict (column, value, aTable) =
    
        let auxTrueFalser (column, value, aTable) =
            ...
        in
    
        let auListMaker (vals, trueFalseList) =
            ...
        in
    
        let trueFalseList = auxTrueFalser (column, value, aTable) in
    
        ... (* body of restrict *)
    

    在这个布局中,restrict 是在顶层定义的(所以只有let,没有in)。其他名称是局部变量(值和函数),因此使用let ... in 定义。

    还请注意,您必须在使用之前定义一个名称。在您的代码中,名称 auxListMaker 在定义之前使用。在上面的布局中,顺序是OK的。

    更新

    回答更多问题。

    let(没有in)的第一种形式的范围是模块的其余部分。对于简单的 .ml 源文件的常见情况,这意味着文件的其余部分。

    是的,上述示意图中显示的restrict 函数将在每次递归调用时重新评估trueFaleList 的值。

    如果您在 OCaml 知道的终端上工作,它会强调它认为您有语法错误的地方。上面原理图布局的前几行的语法显然是可以的。您必须展示您的代码(或显示问题的最小独立子集)和您收到的具体错误消息。

    【讨论】:

    • 非常感谢您的解释!出现的第一个问题是:如果在“in”之后省略表达式 2,let 的范围是什么?我的第二个问题是:restrict 是否会在每次递归调用时评估 trueFalseList?您显示的表格仍然给出语法错误。 auxTrueFalser 的 let 带有下划线。是什么原因?
    • 我编写的其余代码在没有这部分的情况下运行良好。我在这里编写并执行代码:try.ocamlpro.com/fun-demo/tryocaml_index.html#path%3Ddemo
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-30
    • 2018-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多