Haskell:非穷举模式 - 检查列表是否上升 [英] Haskell: Non-exhaustive pattern - Checking if list is ascending

查看:174
本文介绍了Haskell:非穷举模式 - 检查列表是否上升的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道为什么我的功能不起作用。我已经浏览了所有关于非穷尽函数的帖子,但是我的函数完成了所有可能的选项,据我所知。

 升序:: [Int]  - > Bool 
升序[] =错误给出空列表
升序[x] =真
升序[x,y] | y> = x = True
| x< y = False
ascending(x:y:xs)| y> = x =(升序(y:xs))
| x< y = False

结果:

  *主>升序[] 
***例外:空列表给出
* Main>升序[1]
True
* Main>升序[1,2]
True
* Main>升序[2,1]
***例外:test01.hs:(51,1) - (56,55):函数中的非穷举模式升序

它适用于一对货币,但如果货币对不升序,则不适用。当我遵循我的代码时,它应该只是返回False。

解决方案

仔细看看 [x,y] pattern:

ascending [x ,y] | y> = x = True
| x< y = False

当应用于 [2,1] code>,第一个后卫被检查并计算为 False (因为2> = 1);然后,第二个警卫被检查,但它也评估为 False (因为1 <2)。因此,使用下一个模式(因为 [2,1] 也匹配(x:y:ys))) ,但是完全一样的事情发生。因为这是最后一种模式,GHC正确地尖叫着你。

你的警卫人员的不平等不是互补的。您的第三个模式应该是 $ b

 升序[x,y] | x< = y =真
| x> y = False

或者,为了留出更少的错误空间,

升序[x,y] | x< = y =真
|否则= False

然而,仍有很大的改进空间。特别是:


  • 第三种模式与第四种模式重叠。

  • 因为你的函数返回一个 Bool ,使用警卫只显式返回一个布尔值是多余的。
  • 因为按照惯例(参见 dfeuer的评论),空列表被认为是升序,你不需要在遇到它时抛出一个错误(除非你遵循你自己的异想天开的约定)。


全部考虑到这一点,你可以简单地写成:

  ascending :: [Int]  - > Bool 
升序(x:y:xs)= x< = y&&升序(y:xs)
升序_ =真

最后,您可以压缩代码还有一些是 zipWith

  ascending :: [Int]  - > Bool 
升序xs =和$ zipWith(< =)xs(tail xs)


I have no idea why my function doesn't work. I have gone through all the posts about non-exhaustive functions but my functions fulfills all possible options as far as I can see.

ascending :: [Int] -> Bool
ascending []                = error "Empty list given"
ascending [x]               = True
ascending [x,y]     | y>=x  = True
                    | x<y   = False
ascending (x:y:xs)  | y>=x  = (ascending (y:xs))
                    | x<y   = False

Result:

*Main> ascending []
*** Exception: Empty list given
*Main> ascending [1]
True
*Main> ascending [1, 2]
True
*Main> ascending [2, 1]
*** Exception: test01.hs:(51,1)-(56,55): Non-exhaustive patterns in function ascending

It works for one pair, but not if the pair is not ascending. When I follow my code it should be just returning False.

解决方案

Have a closer look at the guards for your [x,y] pattern:

ascending [x,y] | y>=x = True
                | x<y  = False

When applied to [2,1], the first guard is checked and evaluates to False (because 2 >= 1); then, the second guard is checked, but it also evaluates to False (because 1 < 2). Therefore, the next pattern is used (because [2,1] also matched (x:y:ys)), but exactly the same thing happens. Because this was the last pattern, GHC rightfully screams at you.

The inequalities in your guards are not complementary. Your third pattern should read

ascending [x,y] | x <= y = True
                | x >  y = False

or, to leave less room for error,

ascending [x,y] | x <= y    = True
                | otherwise = False

However, there is still much room for improvement. In particular:

  • The third pattern overlaps with the fourth one.
  • Because your function returns a Bool, using guards only to explicitly return a Boolean value is redundant.
  • Because, by convention (see dfeuer's comment), the empty list is considered to be ascending, you don't need to throw an error upon encountering it (unless you're following your own whimsical convention).

Taking all this into account, you could have simply written

ascending :: [Int] -> Bool
ascending (x:y:xs) = x <= y && ascending (y:xs)
ascending _        = True

Finally, you can condense the code some more with a combination of and and zipWith:

ascending :: [Int] -> Bool
ascending xs = and $ zipWith (<=) xs (tail xs)

这篇关于Haskell:非穷举模式 - 检查列表是否上升的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆