F# 签名理解:"the -> operator and Compiler Errors"

F# Signature Understanding: "the -> operator and Compiler Errors"

有时我会收到如下所示的错误:

opgave.fsx(28,14): error FS0001: This expression was expected to have type
    'int'
but here has type
    'int -> int'

opgave.fsx(33,35): error FS0001: This expression was expected to have type
    'int list'
but here has type
    'int -> int list -> int list'

令我困惑的是 -> 运算符是什么意思?据我了解,从第一个错误开始,它应该是一个 int,但给出了一个表达式,该表达式采用一个 int 和 returns 另一个 int。也许我误解了?如果我是正确的那么问题到底是什么?我可以发誓我以前做过类似的事情。

这些错误所基于的代码如下所示:

member this.getPixelColors(x,y,p) : int list =
    let pixel = image.GetPixel(x,y)
    let stringPixel = pixel.ToString()
    let rec breakFinder (s:string) (h:int) =
      match s.[h] with
      |',' -> s.[9..(h-1)] |> int
      |_ -> (breakFinder(s (h+1))) // this is line 28
    let rec yello x y p =
      match x with
      |l when l = imageW -> match y with
                            |k when k = imageH -> p@[(breakFinder stringPixel 0)]
                            |_ -> yello((0)(y+1)(p@[(breakFinder stringPixel 0)])) // this is line 33
      |_ -> yello((x+1)(y)(p@[(breakFinder stringPixel 0)])) // there is an error in this line aswell identical to line 33
    yello 0 0 []

谁能让我明白,这样我以后就可以自己处理这个问题了?

阅读F#函数签名时,箭头(->)是分隔符,您可以阅读以下签名:

int -> int -> string

例如作为一个函数需要 2 ints 和 returns a string。像这样呈现的原因之一是因为您还可以将此函数视为采用 1 int 和 returns 的函数,而您也可以将其视为采用 1 int 和 [=39 的函数=]一个string,这个叫偏应用

在你的情况下,我会使用错误中的行号来帮助你查明问题所在。 所以在第 28 行,你可以给它一个函数,它接受一个 int 和 returns 一个 int,但它想要一个 int 值,也许你忘了调用该函数有输入? 在第 33 行,它想要 int list,这是 list<int> 的另一种表达方式。但是,您给了它一个函数,该函数接受 intlist<int> 和 returns list<int>。同样,也许您需要使用两个输入调用此函数以满足您的类型约束。

编辑:再看一遍,我想我能猜出哪些行是错误的。看起来当您调用其中一些函数时,您将多个参数放在括号中。 尝试将您的代码更新为:

member this.getPixelColors(x,y,p) : int list =
    let pixel = image.GetPixel(x,y)
    let stringPixel = pixel.ToString()
    let rec breakFinder (s:string) (h:int) =
      match s.[h] with
      |',' -> s.[9..(h-1)] |> int
      |_ -> (breakFinder s (h+1))
    let rec yello x y p =
      match x with
      |l when l = imageW -> match y with
                            |k when k = imageH -> p@[(breakFinder stringPixel 0)]
                            |_ -> yello 0 (y+1) (p@[(breakFinder stringPixel 0)])
      |_ -> yello (x+1)(y)(p@[(breakFinder stringPixel 0)])
    yello 0 0 []

例如,要调用具有签名 string -> int -> intbreakFinder,您可以这样做:let number = breakFinder "param1" 42