为什么我的电脑不允许我向顾客打招呼?

发布于 2024-12-10 09:23:58 字数 1348 浏览 0 评论 0原文

我正在写一份申请来更换我们的技术支持部门。当客户需要技术支持时,我们只需向他邮寄一张包含此应用程序的软盘,他只需将其放入计算机洞中并安装即可。他们只需输入问题,程序就会输出解决方案。

我尝试用 F# 编写它,但 F# 不喜欢它。我编写了这个简单的递归函数,向客户显示一条问候消息,但 F# 告诉我“不,这段代码很糟糕”。我非常有信心我的代码很好,并且不明白为什么 F# 认为它如此糟糕。

这是我的代码:

open System

let rec GreetCustomer message =
    let DisplayMessage message =
        Console.WriteLine(message + " " : string) |> ignore
        GreetCustomer
    DisplayMessage(x)

Console.WriteLine("Please do the needful by telling us your name?");
let CustomerName = Console.ReadLine()

GreetCustomer("Hello,")(CustomerName)("!")("How")("to")("help")("you")("today?")

F# 告诉我

类型不匹配。期待 'a 但给出 'b -> 'a 当统一 ''a' 和 ''b 时,结果类型将是无限的 -> '一'

当然,结果类型是无限的。我希望能够将方法调用链接到无限次。我不明白为什么 F# 不喜欢无限类型;我可以用 Javascript 编写相同的程序,没有任何问题:

GreetCustomer = function(message) {
  DisplayMessage = function(message) {
    document.write(message + " ");
    return GreetCustomer; 
  };
  return DisplayMessage(message); 
};

CustomerName = prompt("Please do the needful by telling us your name?");

GreetCustomer("Hello,")(CustomerName)("!")("How")("to")("help")("you")("today?");

并且它具有我想要的输出:

你好,彼得!今天如何帮助您?

如果它在 Javascript 中有效,那么肯定有办法在 F# 中做到这一点。

如何修复我的 F# 程序,使其不会抱怨无限类型?

I am writing an application to replace our technical support department. When a customer needs technical support, we will simply mail him a floppy disk containing this application, which he can simply put into his computer hole and install it. They just type in their problem and the program will output the solution.

I tried writing it in F#, but F# doesn't like it. I wrote this simple recursive function that shows a greeting message to the customer, but F# tells me "no, this code is bad". I'm quite confident that my code is good, and can't figure out why F# thinks it's so bad.

This is my code:

open System

let rec GreetCustomer message =
    let DisplayMessage message =
        Console.WriteLine(message + " " : string) |> ignore
        GreetCustomer
    DisplayMessage(x)

Console.WriteLine("Please do the needful by telling us your name?");
let CustomerName = Console.ReadLine()

GreetCustomer("Hello,")(CustomerName)("!")("How")("to")("help")("you")("today?")

and F# tells me

Type mismatch. Expecting a 'a but given a 'b -> 'a The resulting type would be infinite when unifying ''a' and ''b -> 'a'

Of course the resulting type is infinite. I want to be able to chain the method calls up to an infinite number of times. I don't understand why F# doesn't like infinite types; I can write the same program in Javascript without any issues:

GreetCustomer = function(message) {
  DisplayMessage = function(message) {
    document.write(message + " ");
    return GreetCustomer; 
  };
  return DisplayMessage(message); 
};

CustomerName = prompt("Please do the needful by telling us your name?");

GreetCustomer("Hello,")(CustomerName)("!")("How")("to")("help")("you")("today?");

and it has exactly the output I want:

Hello, Peter ! How to help you today?

If it works in Javascript, surely there must be a way to do it in F#.

How can I fix my F# program so that it won't complain about infinite types?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

友欢 2024-12-17 09:23:58

我在评论中链接的问题对此进行了广泛的阐述。在 F# 中,有多种方法可以实现此目的,但没有一种方法可以为您提供所需的语法。以下答案已经尽善尽美了。

https://stackoverflow.com/questions/2679547/function-which-returns-itself/ 2684005#2684005
https://stackoverflow.com/questions/2679547/function-which-returns-itself/ 2679578#2679578

简而言之,这是类型推断的限制。正如编译器抱怨的那样,返回自身的函数的类型无法确定;它是无限的。

编辑

这是我首选的解决方法(结合我链接的问题的答案):

type Inf<'T> = delegate of 'T -> Inf<'T>

let rec makeInfinite f = 
  fun x -> 
    f x |> ignore
    Inf(makeInfinite f)

let (+>) (inf:Inf<_>) arg = inf.Invoke(arg)

let GreetCustomer = makeInfinite (printf "%s")

GreetCustomer "Hello " +> "there, " +> "how " +> "are " +> "you?" |> ignore

The question I linked in the comments elaborates on this extensively. There are ways to do this in F#, but none will give you the syntax you want. The following answers are about as good as it gets.

https://stackoverflow.com/questions/2679547/function-which-returns-itself/2684005#2684005
https://stackoverflow.com/questions/2679547/function-which-returns-itself/2679578#2679578

In short, this is a limitation of type inference. As the compiler complains, the type of a function which returns itself cannot be solved; it's infinite.

EDIT

This is my preferred workaround (combining answers from the question I linked):

type Inf<'T> = delegate of 'T -> Inf<'T>

let rec makeInfinite f = 
  fun x -> 
    f x |> ignore
    Inf(makeInfinite f)

let (+>) (inf:Inf<_>) arg = inf.Invoke(arg)

let GreetCustomer = makeInfinite (printf "%s")

GreetCustomer "Hello " +> "there, " +> "how " +> "are " +> "you?" |> ignore
洒一地阳光 2024-12-17 09:23:58

丹尼尔链接到的答案应该告诉您如何解决该问题。

原则上,我认为 F# 可以根据您的定义将诸如 ('b -> 'a) 之类的类型推断为 'a (这不是有效的 F# 语法)。相关语言 OCaml 提供了 -rectypes 选项允许编译器推断这样的循环定义,但据我了解,默认情况下该标志未启用,因为推断的循环类型几乎总是表明程序员犯了错误。

The answers that Daniel linked to should tell you how to work around the problem.

In principle, I think that it would be possible for F# to infer a type such as ('b -> 'a) as 'a given your definition (which isn't valid F# syntax). The related language OCaml provides a -rectypes option to allow the compiler to infer cyclic definitions like this, but as I understand it the flag isn't enabled by default because inferred cyclic types are almost always an indication that the programmer has made a mistake.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文