Functional programming 以下OCaml代码段中的错误是什么?

Functional programming 以下OCaml代码段中的错误是什么?,functional-programming,ocaml,Functional Programming,Ocaml,代码: let ab=let a='a'in let b='b'in(Char.lowercase b)in a::[b] 我正在学习let关键字。我希望表达式的计算结果为字符列表['a','b'],但我一直得到错误 错误:未绑定值a 我不知道为什么会这样。据我所知,我可以继续使用letinsidelet来创建新的绑定,并且我已经使用let在开始时将a绑定到'a',因此它在内部范围中也应该有一个有效值,对吗 我知道我可以简单地做b='b'而不是(Char.lowercase b)中的b='b',

代码:
let ab=let a='a'in let b='b'in(Char.lowercase b)in a::[b]

我正在学习
let
关键字。我希望表达式的计算结果为字符列表
['a','b']
,但我一直得到错误

错误:未绑定值a

我不知道为什么会这样。据我所知,我可以继续使用
let
inside
let
来创建新的绑定,并且我已经使用
let
在开始时将
a
绑定到
'a'
,因此它在内部范围中也应该有一个有效值,对吗


我知道我可以简单地做
b='b'
而不是(Char.lowercase b)
中的
b='b',但我正在试验我能做什么和我不能做什么,对我来说这也应该有效。

你在
关键字中有太多
。最顶端的
let
中不应包含相应的

let ab =
  let a = 'a' in
    let b = 'B' in
      (Char.lowercase b) in
        a :: [b];;
重新这样写:

let ab =
  let a = 'a' in
    let b = 'B' in
      a :: [Char.lowercase b];;
let ab =
  let a = 'a'
  and b = 'B' in
    a :: [Char.lowercase b];;
事实上,由于
let b
表达式没有引用
a
,因此可以这样编写:

let ab =
  let a = 'a' in
    let b = 'B' in
      a :: [Char.lowercase b];;
let ab =
  let a = 'a'
  and b = 'B' in
    a :: [Char.lowercase b];;

您在
关键字中有太多的
。最顶端的
let
中不应包含相应的

let ab =
  let a = 'a' in
    let b = 'B' in
      (Char.lowercase b) in
        a :: [b];;
重新这样写:

let ab =
  let a = 'a' in
    let b = 'B' in
      a :: [Char.lowercase b];;
let ab =
  let a = 'a'
  and b = 'B' in
    a :: [Char.lowercase b];;
事实上,由于
let b
表达式没有引用
a
,因此可以这样编写:

let ab =
  let a = 'a' in
    let b = 'B' in
      a :: [Char.lowercase b];;
let ab =
  let a = 'a'
  and b = 'B' in
    a :: [Char.lowercase b];;

根据评论中的讨论,如果您想要表达,我还建议:

let ab =
  let a = 'a' in
  let b = 'B' in
  a::[Char.lowercase b]
in
(* The rest of your code. *)
问题是你的表达是这样的:

let ab =
  let a = 'a' in
  let b = 'B' in
  Char.lowercase b   (* Result: ab gets bound to 'b'. *)
in
a :: [b]             (* a and b aren't visible out here! *)

我还建议使用类似于此的缩进样式,以帮助您清楚地看到这些内容。OCaml程序员通常在let之前中断行。如果有
让p=e在e'
中,并且
e
e'
不适合一行,则缩进
e
,但不要缩进
e'
。通过这种方式,您可以快速看到
p
的绑定在哪些表达式中可见,并且可以看到
e
中的任何绑定在
e'
中不可见。根据评论中的讨论,如果您想要表达式,我还建议:

let ab =
  let a = 'a' in
  let b = 'B' in
  a::[Char.lowercase b]
in
(* The rest of your code. *)
问题是你的表达是这样的:

let ab =
  let a = 'a' in
  let b = 'B' in
  Char.lowercase b   (* Result: ab gets bound to 'b'. *)
in
a :: [b]             (* a and b aren't visible out here! *)

我还建议使用类似于此的缩进样式,以帮助您清楚地看到这些内容。OCaml程序员通常在let之前中断行。如果有
让p=e在e'
中,并且
e
e'
不适合一行,则缩进
e
,但不要缩进
e'
。通过这种方式,您可以很快看到
p
的绑定在哪些表达式中可见,并且可以看到
e
中的任何绑定在
e
中都不可见,这是有效的,但我不确定我是否理解为什么我这样写会导致
a
变得无界。我认为这个错误具有误导性。错误出现在
中的(Char.lowercase b)中。这几乎就像
中的第二个
将您带到顶级范围(不再定义
a
)。如果我理解正确,我们的绑定是否只有在表达式
(Char.lowercase b)
之前才有效,然后我们会丢失所有绑定?如果是这样,那么为什么编译器没有抛出
b
也是无界的错误?而且,是的,
let
绑定是它们定义的范围的本地绑定。顶层
let
绑定可用于模块。嵌套的
let
绑定仅在定义结束之前可用。如果将表达式插入括号,则会在(a::[b])中获得
let ab=(let a='a'in(let b='b'in(Char.lowercase b)))
。这意味着您正在
a::[b]
中绑定
ab
a
b
仅在其结果绑定到
ab
的表达式中可见。顺便说一句,很好的名字:)编辑:换句话说,
ab
被绑定到小写的
“b”
,而
a
b
只有在计算小写的
“b”时才可见
。这是可行的,但我不确定我是否理解为什么我这样写会导致
a
变得无界。我认为这个错误有误导性。错误出现在
中的(Char.lowercase b)中。这几乎就像
中的第二个
将您带到顶级范围(不再定义
a
)。如果我理解正确,我们的绑定是否只有在表达式
(Char.lowercase b)
之前才有效,然后我们会丢失所有绑定?如果是这样,那么为什么编译器没有抛出
b
也是无界的错误?而且,是的,
let
绑定是它们定义的范围的本地绑定。顶层
let
绑定可用于模块。嵌套的
let
绑定仅在定义结束之前可用。如果将表达式插入括号,则会在(a::[b])中获得
let ab=(let a='a'in(let b='b'in(Char.lowercase b)))
。这意味着您正在
a::[b]
中绑定
ab
a
b
仅在其结果绑定到
ab
的表达式中可见。顺便说一句,好名字:)编辑:换句话说,
ab
被绑定到小写的
“b”
,而
a
b
的名字只有在你计算小写的
“b”
时才可见。这就解释了一切!谢谢!!这就解释了一切!非常感谢<代码>a::[b]
可以简单地写
[a;b]
a:[b]
可以简单地写
[a;b]