F#"此规则永远不会匹配"表达式在NOT递归函数中

时间:2014-12-29 20:29:23

标签: f# pattern-matching

我有这样一个功能:

let RotateFace (face: int, turns: int) =
    match face with
        | upperface -> 
            TiltCube(2)
            TwistCube(turns)
            TiltCube(2)
        | leftface -> 
            TiltCube(3)
            TwistCube(turns)
            TiltCube(1)
        | frontface -> 
            TurnCube(1)
            TiltCube(3)
            TwistCube(turns)
            TiltCube(1)
            TurnCube(3)
        | rightface -> 
            TiltCube(1)
            TwistCube(turns)
            TiltCube(3)
        | backface -> 
            TiltCube(3)
            TwistCube(turns)
            TiltCube(1)
        | downface -> 
            TurnCube(3)
            TiltCube(3)
            TwistCube(turns)
            TiltCube(1)
            TurnCube(1)
        | _ -> ()

我有一个"这个规则永远不会匹配"我的案例有问题"'                       39;,' downface',' _'。"。

我看过这个链接;

f# match expression - "rule will never be matched"

但说实话,我不明白我该如何处理我的案子。

2 个答案:

答案 0 :(得分:8)

你不能与一个变量匹配,我的意思是你可以但是如果你这样做会发生什么变化将被绑定到那个值而且在我看来并不是你的意思试图做,否则你的代码中的第一个案例将" eat"所有其他情况以及以下规则永远不会匹配的原因。

您可以匹配条件:

let RotateFace (face: int, turns: int) =
    match face with
        | x when x = upperface -> 
            TiltCube(2)
            TwistCube(turns)
            TiltCube(2)

或使用literal attribute声明upperface和其他变量作为常量:

[<Literal>]
let Upperface  = 4

let RotateFace (face: int, turns: int) =
    match face with
        | Upperface -> 
            TiltCube(2)
            TwistCube(turns)
            TiltCube(2)

答案 1 :(得分:3)

从技术上讲,Gustavo's answer是问题的正确答案,并显示了一些关于模式匹配的详细信息。但是,在您的情况下,您可能希望与discriminated union个案例匹配,而不是与整数匹配。

换句话说,变量face可以使用Face类型而不是int

type [<RequireQualifiedAccess>] Face =
    Front | Back | Top | Bottom | Left | Right

RequireQualifiedAccess属性意味着您必须编写Face.Front而不是Front。如果案件从不意味着什么,你可以把它留下来。无论如何,使用上面的定义,RotateFace变为:

let RotateFace (face, turns: int) =
    match face with
    | Face.Top -> 
        TiltCube(2)
        TwistCube(turns)
        TiltCube(2)
    | Face.Left -> 
        TiltCube(3)
        TwistCube(turns)
        TiltCube(1)
    // and so on

这样,您也不需要_ -> ()大小写,因为编译器知道您的模式匹配处理所有面。

Ohhhhhh!你正在用Lego Mindstorms和F#构建一个3x3x3 Rubick的立方体解算器!最后,我看到了连接这些问题的原因。:D