.netfunctional-programmingf#

F# functional programming: why am I getting type mismatch errors?


As an admitted newbie to F#, I am having a hard time understanding why I am getting this error. Here is my admittedly trivial and redundant code:

open System
open System.Globalization

let toUpperCase (input: string) = 
    input.ToUpper()

let uCaseAll (input: string) = 
    input.Split()
    |> Array.map toUpperCase
    |> String.concat " "

[<EntryPoint>]
let main argv =
    let text = "You’re in the right place. Tell us what titles or genres you’ve enjoyed in the past, and we’ll give you surprisingly insightful recommendations."
    printfn "Result: %s" uCaseAll text

The error I receive is:

Type mismatch. Expecting a
    'string -> 'a -> int'    
but given a
    'string -> unit'    
The type ''a -> int' does not match the type 'unit'

This expression was expected to have type
    'string'    
but here has type
    'string -> string' 

This confuses me, because my functions are clearly defined to accept a string and return a string. Yet the compiler thinks I am doing something with ints and uints.

What am I doing wrong?


Solution

  • One problem is in the last line. F# thinks you are calling printfn with three arguments, instead of two. You just need a pair of parentheses to call uCaseAll text first, and then send that result to printfn:

    printfn "Result: %s" (uCaseAll text)
    

    Since you're using a main function, you also need to return an integer at the end. 0 is usually used by convention. Or, to make things simpler, just get rid of main altogether, which gives you the following complete program:

    let toUpperCase (input: string) = 
        input.ToUpper()
    
    let uCaseAll (input: string) = 
        input.Split()
        |> Array.map toUpperCase
        |> String.concat " "
    
    let text = "You’re in the right place. Tell us what titles or genres you’ve enjoyed in the past, and we’ll give you surprisingly insightful recommendations."
    printfn "Result: %s" (uCaseAll text)
    

    You don't need either of the open statements.