【问题标题】:F# in Visual Studio Code type incorrectVisual Studio Code 中的 F# 类型不正确
【发布时间】:2020-03-05 15:18:14
【问题描述】:

我正在编写一个函数来处理 F# 中的后缀评估。这就是我目前所拥有的评估功能

//Postfix evaluation of string expr given variables bound to values as specified in vars
    let (numSt:int list) = []
    let rec innerEval (vars:(List<(string * int)>)) (stack: int list) (expr:string) =
    //Head and Tail for stack, head and tail for expr
        let chExpr = Seq.toList expr
        match expr with 
        |[] -> stack.Head
        |head::tail ->
            if head = '+' then
                let pushVal = stack.Head + stack.Tail.Head
                let newStack = pushVal::stack.Tail
                innerEval vars newStack tail
            elif head = '-' then 
                let pushVal = stack.Head - stack.Tail.Head
                let newStack = pushVal::stack.Tail
                innerEval vars newStack tail
            elif head = '/' then 
                let pushVal = stack.Head / stack.Tail.Head
                let newStack = pushVal::stack.Tail
                innerEval vars newStack tail
            elif head = '*' then 
                let pushVal = stack.Head * stack.Tail.Head
                let newStack = pushVal::stack.Tail
                innerEval vars newStack tail
            elif head = '$' then 
                let fstSt = stack.Head
                let sndSt = stack.Tail.Head
                let nhead = [fstSt; sndSt]
                let st =  nhead @ stack.Tail.Tail
                innerEval vars st tail
            elif head = '@' then 
                let nhead = tail.Head
                let newVars = newVarList nhead vars stack.Head //helper function newVarList
                innerEval newVars stack.Tail tail

             //else it's a letter that needs to give back a number

            else 
                let addNum = (getVal head vars) //get the number
                let newStack = addNum::stack //push that onto stack
                innerEval vars newStack expr //return to recursion on newStack

我知道这很罗嗦,但是当我尝试运行此代码时,我在代码中收到一个错误,显示为

pa4.fs(1194,38): error FS0001: This expression was expected to have type
    'string'    
but here has type
    'char'

所以我的问题不一定是关于代码本身(除非有人能看出它有什么问题),而是关于错误消息:显然这意味着我有一个类型不正确的元素,但是 (1194, 38 ) 意思是?我假设是第 38 行,但每次运行代码时都会增加较大的数字,我不确定这意味着什么?

对不起,如果这是一个菜鸟问题,这个任务几乎没有方向!

【问题讨论】:

  • 首先,菜鸟问题通常是最好的问题,因为我们希望让刚入门的人更容易! 1194 是控制台中的行,34 是列。这就是为什么这个数字每次都变大的原因,因为它也有你以前评估过的东西。我个人不喜欢这种默认设置,它对于只运行一小部分代码的人来说效果很好,但对于想要运行整个代码的人来说,它可能是一个痛点。

标签: f# f#-interactive


【解决方案1】:

您的一个功能是希望得到一个“字符串”(我喜欢将许多字符想象成一个字符串保存的派对字母),但得到一个 'c' 'h' 'a' ,'r' (单个字符)。我怀疑 newvarlist 因为 innereval 看起来不错?不看功能很难说,但是你应该可以用鼠标悬停在它们上面。带有 ionide 扩展的 Visual Studio 和 Visual Studio 代码都支持这一点。您甚至会在不起作用的代码行上看到红色的波浪线。让我知道这是否有帮助!

【讨论】:

    【解决方案2】:

    F# 的T listT 类型的不可变单链表,它不能与string 互换,string 是它自己的原始类型。但是,string 隐含地是seq&lt;char&gt;,这就是为什么你可以使用像Seq.toList expr 这样的函数。

    因此,您将无法使用列表模式进行匹配。

    let rec innerEval (vars:(List<(string * int)>)) (stack: int list) (expr:string) =
        match expr with //won't compile because expr isn't list
        | [] -> stack.Head
        | head::tail ->
             innerEval vars newStack tail //won't compile because tail is char list
    

    更简单的解决方案是将innerEval (expr: string) 的签名更改为innerEval (expr: char list),从而简化转换。

    【讨论】:

    • @Hailey Dice 你的问题“我知道这很罗嗦”。比修复特定错误更重要的是知道如何创建用于诊断错误和提出问题的最小示例。这个答案显示了如何做到这一点。您的代码所做的是无关紧要的,因此您不需要保留功能。如果你在保留错误的同时继续减少它,你最终会得到这样的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 2019-10-18
    • 1970-01-01
    • 2021-07-09
    • 2021-06-25
    相关资源
    最近更新 更多