Sml 检查标准ML中的数字是否为斐波那契

Sml 检查标准ML中的数字是否为斐波那契,sml,smlnj,Sml,Smlnj,我试图写一个代码,检查数字是否是斐波那契或不是在ML。我是一个初学者。帮我找出我的代码有什么问题 fun isfib(n :int): bool= let val a1=1; val a2=1; val temp=0; in while a2<n do ( a1=temp a2=a1 a2=temp+a2 ) if a2=n then true else false end; fun-isfib(n:int):bool= 让 vala1

我试图写一个代码,检查数字是否是斐波那契或不是在ML。我是一个初学者。帮我找出我的代码有什么问题

fun isfib(n :int): bool=
let
  val a1=1;
  val a2=1;
  val temp=0;
in
  while a2<n do (
    a1=temp
    a2=a1
    a2=temp+a2
  )
  if a2=n then true
  else false
end;
fun-isfib(n:int):bool=
让
vala1=1;
vala2=1;
val-temp=0;
在里面
而a2
=
是SML中的相等运算符,而不是赋值运算符。因此,上述代码与此等效:

false (* because a1 is 1, but temp is 0 *)
true (* because a1 and a2 are both 1 *)
true (* because 1 = 0 + 1 *)
所以在循环中有三个没有副作用的表达式,所以它不会做任何事情

很明显,您实际上想要更改这些变量的值,但您不能这样做。SML中的变量是不可变的-设置后不能更改它们。因此,即使是像
a2
这样的while条件也没有意义,因为
a2
n
不能改变,所以条件要么总是真的,要么总是假的。如果您想使用这样的while循环,您应该查看
ref
类型,它允许您创建可用于模拟可变变量的可变值


也就是说,使用while循环和变异并不是惯用的SML。SML中的变量不可变有一个原因:语言设计者希望鼓励您不要依赖变异(因此也不要依赖while循环)。SML中循环的惯用方法是使用高阶函数(如
map
filter
foldl
等)或递归。对于您的问题,递归函数最有意义。

如果您描述当前的问题,可能会更容易帮助您。
false (* because a1 is 1, but temp is 0 *)
true (* because a1 and a2 are both 1 *)
true (* because 1 = 0 + 1 *)