F #: Ошибка несоответствия типов при попытке вернуть мой результат из функции - PullRequest
0 голосов
/ 27 сентября 2018

Итак, у меня есть эта функция, которая вычисляет процент частоты каждой буквы, заданной строкой.эта функция называется «частота» и использует другие вспомогательные функции, которые я написал («count», «lowerCases» и «процент»).Но когда я пытаюсь вернуть свой результат, я получаю ошибку несоответствия.Вот мой код ниже:

let frequency(str:string) : float  = 
    let myList = ['a'..'z']
    for i=0 to 25 do 
      printf "%f" (percent ((count myList.[i] str) (lowerCases str)))

System.Console.WriteLine(frequency"hello world")

Я продолжаю получать эту ошибку:

This expression was expected to have type float but here has type unit

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

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Функция F # связывает одно значение единственного выражения в своем теле (то есть, то, которое следует последним после всех let -привязок, проще говоря. В вашем случае это выражение

for i=0 to 25 do 
  printf "%f" (percent ((count myList.[i] str) (lowerCases str)))

Он имеет тип unit, что означает, что он не возвращает ничего полезного, кроме специального значения (), в то время как привязка let frequency ... : float = говорит, что он возвращает float. Отсюда ошибка.

printf уже печатает на консоль. Вероятно, вам нужно:

let frequency(str:string) : unit  = 
    let myList = ['a'..'z']
    for i=0 to 25 do 
      printf "%f" (percent ((count myList.[i] str) (lowerCases str)))

do frequency "hello world"

Идиоматично опускать аннотацию : unit в такой функции и позволить компилятору выводить тип возвращаемого значения. Этот код не отображаетF # слава, естественно, но выполняет свою работу.

Поскольку кажется, что вы изучаете язык, вот упражнение, возможно, на будущее. Ваша функция объединяет вычисление частоты букв и печать их, а функциональное программирование - это все о композиции. Что делать, если вы хотите отобразить результат в окне вместо его вывода на консоль или отформатировать его иначе?ently?Попробуйте написать две функции: одна возвращает структуру данных с частотами букв, а другая печатает ее.

0 голосов
/ 27 сентября 2018

Вы объявили функцию как возвращающую число с плавающей точкой:

let frequency(str:string) : float  = 

Однако ваша функция не возвращает значение с плавающей точкой, она просто выводит один из них:

printf "%f" (percent ((count myList.[i] str) (lowerCases str)))

printf функция возвращает unit, что означает, что она фактически не имеет возвращаемого значения (имеет постоянное возвращаемое значение типа singleton unit).

Есть две вещи, которые, как я вижу, вам нужно исправить здесь.Вам нужно вернуть значение из функции (если оно будет значением последней строки), и я думаю, вы захотите, чтобы тип возвращаемого значения был списком или картой, а не одним значением (иначе, как бы вы узналидве буквы, к которым применяется частота)?

Вы можете достичь этого результата, просто вызвав функцию percent из List.map, а затем сделав из списка Map:

let frequency(str:string) : Map<char, float>  = 
    ['a'..'z']
    |> List.map (fun letter -> letter, (percent ((count letter str) (lowerCases str))))
    |> Map.ofList
...