Home Articles

功能上的非详尽模式?

Asked
Viewed 769 times
0

我在这段代码中有错误:

ordena :: (Ord a) => (a,a,a) -> (a,a,a)
ordena (x,y,z)
  | x > y     =  ordena (y,x,z)
  | x > z     =  ordena (z,y,x)
  | y > z     =  ordena (x,z,y)

1 Answer

  • 1

    您没有处理所有可能的情况:

    Prelude> :{
    Prelude| let ordena :: (Ord a) => (a,a,a) -> (a,a,a)
    Prelude|     ordena (x,y,z) | x > y     =  ordena (y,x,z)
    Prelude|                    | x > z     =  ordena (z,y,x)
    Prelude|                    | y > z     =  ordena (x,z,y)
    Prelude| :}
    Prelude> 
    Prelude> ordena 0 0 0
    
    <interactive>:22:1:
        Couldn't match expected type ‘Integer -> Integer -> t’
                    with actual type ‘(a0, a0, a0)’
        Relevant bindings include it :: t (bound at <interactive>:22:1)
        The function ‘ordena’ is applied to three arguments,
        but its type ‘(a0, a0, a0) -> (a0, a0, a0)’ has only one
        In the expression: ordena 0 0 0
        In an equation for ‘it’: it = ordena 0 0 0
    

    您需要在模式匹配中添加至少catch-all case:

    ordena :: (Ord a) => (a,a,a) -> (a,a,a)
    ordena (x,y,z) | x > y     =  ordena (y,x,z)
                   | x > z     =  ordena (z,y,x)
                   | y > z     =  ordena (x,z,y)
                   | otherwise =  ...
    

    或者,您可能希望将 otherwise 案例拆分为两个或更多具体案例,但我可以't tell you what those are because I don'知道 ordena 应该代表什么 .


    但一般情况下,您确实应该在问题中包含错误消息 . 现在,我们只能猜测它是一个运行时错误,而不是编译错误,但有时候这根本不是很明显,但即使是这样,你也应该包含错误 .

Related