【问题标题】:Why does if expression ignore condition in F#?为什么 if 表达式会忽略 F# 中的条件?
【发布时间】:2014-03-12 07:12:02
【问题描述】:

我正在尝试检查一个数组是否已排列。问题是在 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()

正因为如此,它总是显示数组虽然不是排列的

【问题讨论】:

    标签: f#


    【解决方案1】:

    默认情况下,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 &lt;- 0 然后更改值。

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

    【讨论】:

      【解决方案2】:

      你的代码有问题

       ordenado = 1
      

      这不是分配而是比较。 在 F# 中 = 运算符有两种含义,绑定(不是赋值)到 let 语句或比较

      您不能分配给 let 绑定字段,它们是不可变的。要分配它,您应该使其可变并使用

      【讨论】:

        猜你喜欢
        • 2021-10-20
        • 1970-01-01
        • 2012-04-20
        • 1970-01-01
        • 2019-03-05
        • 2014-05-16
        • 2022-07-14
        • 2017-08-11
        • 1970-01-01
        相关资源
        最近更新 更多