我应该如何终止F#中的func

时间:2018-04-28 22:01:20

标签: f#

let Trans(DirPath:string) =
    if ( numOfVmFiles(DirPath) > 1) then //if there are more than 1 vm files in the directory
            Init("")
    let VmFiles = ListOfVmFiles(DirPath)
    for VmFile in VmFiles do // for each vm file
            ReadFile(VmFile)

我收到了这个错误: 在此之后的错误阻止'让'尚未完成。期待一个表达。 我该怎么写?thznk你

3 个答案:

答案 0 :(得分:3)

现有答案为您提供了有关如何更好地编写代码的良好提示。你说你收到了一个错误:

  

阻止此'let'未完成。期待一个表达。

这通常表示在函数结束后缺少=或错误的缩进(或者像这样容易遗漏的语法错误)。在你发布的片段中,所有语法对我来说都很好,所以我怀疑其他地方也有问题。以下没有错误:

let numOfVmFiles a = 0
let Init a = ()
let ListOfVmFiles a = []
let ReadFile a = ()

let Trans(DirPath:string) =
    if ( numOfVmFiles(DirPath) > 1) then 
            Init("")
    let VmFiles = ListOfVmFiles(DirPath)
    for VmFile in VmFiles do // for each vm file
            ReadFile(VmFile)

您会收到两个警告 - 因为变量名称应为camelCase而不是PascalCase,但没有错误。正如其他人所说,你应该让InitReadFile返回一些内容,然后你需要收集结果(以使你的代码更具功能性),但这是一个单独的问题。

答案 1 :(得分:1)

问题是该函数没有返回值。函数必须始终返回值。如果没有要返回的内容,请返回unit。您可以将单位返回为()

我在这里做了一些可能不正确的假设,但我试图弄清楚它们是什么。在trans函数中,我还展示了如何指定返回类型。通常最好让编译器推断出类型,直到它不能。将鼠标悬停在函数上,查看编译器告诉您的类型。 string -> int -> string list表示函数接受字符串和int,并返回字符串列表。

let init dirName = () //unit is returned... kind of like void but is actually a return value
let listOfVmFiles dirName = ["some";"files"] // list of string
let readFile path = "content of file" //string

let trans(dirPath:string) : string list = // takes a string and returns a list of string represented as string-> string list
    let vmFiles = listOfVmFiles(dirPath) // get files from path
    if(vmFiles.Length > 1) then init("") // init if more than 1 file
    List.map readFile vmFiles // return a list of the content of the files

如果某个功能正在执行副作用并且没有返回某些内容,则可以这样做:

let trans(dirPath:string) : unit =
    let vmFiles = listOfVmFiles(dirPath)
    if(vmFiles.Length > 1) then init("")
    List.map readFile vmFiles |> ignore //ignore the result
    ()

这会忽略将readFile函数映射到列表上的结果,然后使用unit返回()

我建议fsharp for fun and profit学习fsharp。 希望这会有所帮助,祝你好运。虽然语法似乎很奇怪,但最初坚持下去。太棒了!

答案 2 :(得分:1)

在F#中,函数返回它计算的最后一个表达式的值。 在您的特定情况下,它返回单位(),因为for循环返回单位,除非它的正文yield的值(在这种情况下,您需要将其包装在seq中)。 正如评论中所提到的,这段代码解析好了 - 你的问题是代码中其他地方未完成的表达。

Devon Buriss的重写是最佳实践的一个很好的例子:

  • 在签名中明确声明函数返回值。
  • ignore函数返回值,如果仅调用该函数的副作用(例如readFileinit(""))。
  • 首选map等功能行为,而不是诸如......之类的命令。

顺便说一下,如此严重依赖副作用可能会在其他地方造成困难。数据处理的一个更常见的做法是将readFile函数作为seq返回文件内容,并将结果传递给下游处理:

List.map readFile vmFiles
|> seq.Concat // concatenate the file outputs
|> processContents

这是否适合您,取决于您打算如何处理每个文件的内容。

相关问题