为什么if表达式忽略F#中的条件?

时间:2014-03-11 10:32:50

标签: f#

我正在尝试检查数组是否已安排。问题是在方法Verificar Fsharp中忽略if和'ordenado'总是取值0.

open System

type VerificarOrden() = 
  let valor = Array.empty
  let (valor : int array) = Array.create 10 1
  let ordenado = 0

  member this.Inicializar() = 
    for f in 0 .. valor.Length - 1 do
      printfn "Introduzaca el valor %d: " f
      let res=System.Console.ReadLine()
      Array.set valor f (System.Int32.Parse(res))

    member this.Verificar() = 
      for f in 1 .. valor.Length - 1 do
        if valor.[f] > valor.[f-1]
        then ordenado = 0
        else ordenado = 1
        printfn "f: %d\nanterior: %d\nordenado: %d\n" valor.[f] valor.[f-1] ordenado

    member this.Imprimir() =
      if ordenado = 0 
      then printfn "La matriz esta ordenada"
      else printfn "La matriz no esta ordenada"

let chekear = VerificarOrden()
chekear.Inicializar()
chekear.Verificar()
chekear.Imprimir()

因此,它始终显示数组已排列,但不是

2 个答案:

答案 0 :(得分:3)

F#中的变量默认是不可变的:它们永远不会更改,也无法更新。所以代码

Type VerificarOrden()
    let ordenado = 0
    ...

基本上意味着ordenado是一个值为0的常量。在条件

    if valor.[f] > valor.[f-1]
    then ordenado = 0
    else ordenado = 1

等号不会更新常量ordenado - 这将毫无意义 - 而是测试 ordenado的值是否为0,返回一个布尔值。上面的代码与

具有相同的语义
    if valor.[f] > valor.[f-1]
    then true
    else false

编译器/解释器可能试图用警告

告诉你
  

警告FS0020:此表达式应为“unit”类型,但类型为“bool”。使用'ignore'丢弃表达式的结果,或'let'将结果绑定到名称。

您希望ordenado变得可变。这就是你想要的,然后:

type VerificarOrden() = 
    ...
    let mutable ordenado = 0

    ...
    if valor.[f] > valor.[f-1]
    then ordenado <- 0
    else ordenado <- 1
    ...

mutable关键字表示可以更改ordenado的值。然后,作业ordenado <- 0会更改值。

顺便说一句,一旦你ordenado变得可变,你的程序仍然有一个错误,它认为序列为0-1-2-3-4-5-6-8-7-9订购。我会把它留作练习; - )

答案 1 :(得分:0)

您的代码存在问题

 ordenado = 1

这不是作业而是比较。 在F#=中,operator有两个含义,绑定(不赋值)给let语句或比较

您不能分配给let bound字段,它们是不可变的。要分配它,你应该使它变为可变并使用&lt; - operator