在F#

时间:2017-04-21 01:58:44

标签: function f# pattern-matching

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

这种模式匹配功能可以很好地处理字符串,但是当我尝试将其转换为比较自定义类型值时,visual studio表示函数未完成,即使语法完全相同。

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建议添加一个显式结果,所以我添加了一个通配符(尽管它应该是不必要的,因为卡片对象不能在没有等级设置的情况下创建)但错误仍然存​​在。

1 个答案:

答案 0 :(得分:1)

您在评论中说过的错误消息如下:

  

此后的块'让'尚未完成。每个代码块都是一个表达式,必须有结果。 '让'不能是块中的最终代码元素。考虑给这个块一个明确的结果。

这与您的match表达式无关,您可以安全地删除_ -> 0行。您看到了该错误,因为某个地方您在代码块中有一个let语句,后面没有其他表达式。即,此代码不合法​​:

let f x =
    let result = x + 5

F#中的所有函数都必须返回一个值,let语句是F#中非常少的一个语句,而不是表达式let 未返回值。因此,当您进入代码块时,必须跟进一个let语句和其他表达式,以便返回值的内容是函数的最后一个表达式。即,:

let f x =
    let result = x + 5
    result

这是合法的。

请注意,适用于模块级别。模块是"容器"包含值,并且本身没有值。 (基本上,它们被编译成静态类)。所以这很好:

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

let语句作为模块中的最后一行是完全可以的(事实上,这是正常的)。但它可能不是函数(或任何其他代码块)中的最后一行,因为函数必须返回一个值。