Kastoli
Kastoli

Reputation: 105

Return an integer value when pattern matching type value in F#

let Greeting name = 
    match name with
    | "Joe" | "Bob" | "Ray" -> "Hello"
    | "Miguel" | "Jose" -> "Hola"
    | _ -> "Don't know what to say"

This pattern matching function works perfectly fine with strings, but when I attempt to convert it to compare custom type values visual studio says the function is unfinished, even though the syntax is exactly the same.

type Suit = Spades | Clubs | Hearts | Diamonds
type Rank = Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack | Queen | King
type Card = { suit: Suit; rank: Rank}

let cardValue (card:Card) = 
    match card.rank with
    | Ace -> 1
    | Two -> 2
    | Three -> 3
    | Four -> 4
    | Five -> 5
    | Six -> 6
    | Seven -> 7
    | Eight -> 8
    | Nine -> 9
    | Ten | Jack | Queen | King -> 10
    | _ -> 0

Visual studio suggested adding an explicit result, so I added a wildcard (even though it should be unnecessary because card objects can't be created without a rank set afaik) but the error persists.

Upvotes: 2

Views: 340

Answers (1)

rmunn
rmunn

Reputation: 36688

The error message you're getting, you've said in the comments, is the following one:

The block following this 'let' is unfinished. Every code block is an expression and must have a result. 'let' cannot be the final code element in a block. Consider giving this block an explicit result.

This has nothing to do with your match expression, and you can safely remove the _ -> 0 line. You're seeing that error because somewhere you have a let statement inside a code block that is not followed by another expression. I.e., this code is not legal:

let f x =
    let result = x + 5

All functions in F# must return a value, and the let statement is one of the VERY few things in F# that is a statement, not an expression. let does not return a value. So when you're inside a code block, you MUST follow up a let statement with some other expression, so that something that returns a value is the last expression of the function. I.e.,:

let f x =
    let result = x + 5
    result

This is legal.

Note that this does not apply at the module level. Modules are "containers" that contain values, and do not have a value themselves. (They get compiled into static classes, basically). So this is fine:

module Foo =
    let f x = x + 1
    let value = 26

It is perfectly okay (in fact, it's normal) for a let statement to be the last line in a module. But it may not be the last line in a function (or any other code block), because functions must return a value.

Upvotes: 1

Related Questions