简体   繁体   English

F#两种不同类型的函数参数

[英]F# Two Different types of Function Arguments

Im trying to make a function that will take a string and an integer as arguments/input. 我试图创建一个函数,将一个字符串和一个整数作为参数/输入。

let rec twoTwo (s : string) (n : int) = 
  match n with 
  |0 -> 0 
  |_ -> s + (twoTwo s (n-1))

printfn "%A" (twoTwo "string" 5)

Here i get the error that the type int does not match the type string. 这里我得到类型int与类型字符串不匹配的错误。 It is beyond me why? 这超出了我的原因? It is in the recursive call that it errors type missmatch. 它在递归调用中是错误类型错配。

What is wrong? 怎么了?

Here's a question to think about: what does your function return? 这是一个值得思考的问题:你的函数会返回什么?

If you look at the first branch of the match , you return an int , but in the second branch you're using your own return value in concatenation with a string , so the return value must be a string. 如果你看的第一支match ,你返回int ,但在第二个分支您正在使用与串联自己的返回值string ,因此,返回值必须是一个字符串。

So which is it? 那是哪个呢? The compiler can't tell which one you meant, so it complains. 编译器无法分辨你的意思,所以它会抱怨。

In response to your comment: 回应你的评论:
The compiler first read the zero in the first branch, and on that basis decided that the function's return must be int . 编译器首先读取第一个分支中的零,并在此基础上确定函数的返回必须为int After that, the compiler encountered the string concatenation, saw that the already-decided return type doesn't fit, and issued an error. 之后,编译器遇到字符串连接,看到已经确定的返回类型不适合,并发出错误。
If the branches were reversed, then the logic would be reversed as well: the compiler would first encounter the concatenation, and on that basis decide that the return type must be string . 如果分支被反转,那么逻辑也将被反转:编译器将首先遇到连接,并在此基础上决定返回类型必须是string After that, it would encounter the zero, see that it doesn't match the previously-decided return type, and complain. 之后,它会遇到零,看到它与先前决定的返回类型不匹配,并抱怨。 In this scenario, the error would have been at the zero. 在这种情况下,错误将为零。
Would you have complained in that case? 那个案子你会抱怨吗? Why? 为什么? How do you expect the compiler to know that the error is at the zero, and not at the concatenation? 您期望编译器如何知道错误是零,而不是连接? All the compiler can possibly know is that the two branches don't match. 所有编译器都可能知道两个分支不匹配。 It doesn't know which one is correct. 它不知道哪一个是正确的。

You think that this is obvious, because you know what you meant to do. 认为这很明显,因为你知道你的意图。 But the compiler doesn't know what you meant to do, it can only see what you wrote. 但是编译器不知道你打算做什么,它只能看到你写的内容。

In a different language, one you could call more "rookie-friendly" , such as, perhaps, C# (or Java), this situation doesn't arise, because you're always forced to explicitly specify all return and parameter types. 在另一种语言中,你可以称之为“菜鸟友好” ,例如C#(或Java),这种情况不会出现,因为你总是被迫明确指定所有的返回和参数类型。 This makes the errors a little more comprehensible, because now the compiler can tell which branch is incorrect: it's the one that doesn't agree with the explicitly declared return type. 这使得错误更容易理解,因为现在编译器可以判断哪个分支不正确:它是与显式声明的返回类型不一致的分支。
But if you think about it, you've merely moved the problem upstream: how does the compiler know that the explicitly declared type is correct? 但是如果你考虑一下,你只是将问题转移到上游:编译器如何知道显式声明的类型是否正确? The compiler simply assumes that the declared type is the ultimate truth, but that's merely a convention. 编译器只是假设声明的类型是最终的事实,但这只是一个约定。 One that is very familiar to you, yes, - but just as arbitrary as reading the program in order. 对你来说非常熟悉,是的,但是就像按顺序阅读程序一样随意。

However, if you find this approach easier for you, you can totally employ it in F# as well. 但是,如果您觉得这种方法更容易,您也可以在F#中完全使用它。 F# allows (though doesn't require ) explicit type specifications in all places where C# does (and then some): F#允许(但不要求 )C#所有地方(然后是一些)的显式类型规范:

let rec twoTwo (s : string) (n : int) : string = 
  match n with 
  |0 -> 0   // Error on this line: this expression was expected to have type string, but here has type int
  |_ -> s + (twoTwo s (n-1))

In fact, adding explicit type specifications is a common debugging technique. 实际上,添加显式类型规范是一种常见的调试技术。 When I find myself with a type mismatch error that's not entirely obvious, I start adding type specifications to things until the error comes into focus. 当我发现自己的类型不匹配错误并不完全明显时,我开始向事物添加类型规范,直到错误成为焦点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM