Почему мой компьютер не позволяет мне приветствовать своих клиентов? - PullRequest
0 голосов
/ 19 октября 2011

Я пишу заявку на замену нашего отдела технической поддержки.Когда клиенту нужна техническая поддержка, мы просто отправим ему дискету с этим приложением, которую он может просто вставить в отверстие своего компьютера и установить.Они просто набирают свою проблему, и программа выводит решение.

Я пытался написать это на 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, но учитывая a b -> a Полученный тип будет бесконечным при объединении 'a' и '' b -> 'a'

Конечно, результирующий тип бесконечен,Я хочу иметь возможность связывать вызовы метода бесконечное количество раз.Я не понимаю, почему 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 #, чтобы она победилане жалуетесь на бесконечные типы?

Ответы [ 2 ]

4 голосов
/ 19 октября 2011

Вопрос, который я связал в комментариях, подробно описывает этот вопрос.Есть способы сделать это в 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
2 голосов
/ 19 октября 2011

Ответы, с которыми связывался Даниил, должны рассказать вам, как обойти эту проблему.

В принципе, я думаю, что F # мог бы вывести тип, такой как ('b -> 'a) as 'a, с учетом вашего определения (что не является допустимым синтаксисом F #). Связанный язык OCaml предоставляет опцию -rectypes , чтобы позволить компилятору выводить циклические определения, подобные этому, но, насколько я понимаю, этот флаг не включен по умолчанию, поскольку выведенные циклические типы почти всегда указывают на Программист допустил ошибку.

...