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你
答案 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
,但没有错误。正如其他人所说,你应该让Init
和ReadFile
返回一些内容,然后你需要收集结果(以使你的代码更具功能性),但这是一个单独的问题。
答案 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
函数返回值,如果仅调用该函数的副作用(例如readFile
和init("")
)。map
等功能行为,而不是诸如......之类的命令。顺便说一下,如此严重依赖副作用可能会在其他地方造成困难。数据处理的一个更常见的做法是将readFile函数作为seq返回文件内容,并将结果传递给下游处理:
List.map readFile vmFiles
|> seq.Concat // concatenate the file outputs
|> processContents
这是否适合您,取决于您打算如何处理每个文件的内容。