Implementation of null function

后端 未结 3 881
盖世英雄少女心
盖世英雄少女心 2021-01-17 07:35

I have to learn Haskell for university and therefor I\'m using learnyouahaskell.com for the beginning.
I always used imperative languages so I decided to practice Haskell

相关标签:
3条回答
  • 2021-01-17 07:58

    Because _ literally means anything apart from explicitly specified patterns. When you specify (_:_) it means anything which can be represented as a list containing at least 1 element, without bothering with what or even how many elements the list actually contains. Since the case with an explicit pattern for empty list is already present, (_:_) might as well be replaced by _.

    However, representing it as (_:_) gives you the flexibility to not even explicitly pass the empty list pattern. In fact, this will work:

    -- | Test whether a list is empty.
    null                    :: [a] -> Bool    
    null (_:_)              =  False
    null _                  =  True
    

    Demo

    0 讨论(0)
  • 2021-01-17 08:13

    You can't just turn the clauses around with your solution:

    mNull' :: [a] -> Bool
    mNull' _  = False
    mNull' [] = True
    

    this will always yield False, even if you pass an empty list. Because the runtime doesn't ever consider the [] clause, it immediately sees _ matches anything. (GHC will warn you about such an overlapping pattern.)

    On the other hand,

    null' :: [a] -> Bool
    null' (_:_) = False
    null' []    = True
    

    still works correctly, because (_:_) fails to match the particular case of an empty list.

    That in itself doesn't really give the two explicit clauses an advantage. However, in more complicated code, writing out all the mutually excluse options has one benefit: if you've forgotten one option, the compiler can also warn you about that! Whereas a _ can and will just handle any case not dealt with by the previous clauses, even if that's not actually correct.

    0 讨论(0)
  • 2021-01-17 08:20

    I'll add on to what leftaroundabout said. This is not really a potential concern for the list type, but in general, data types sometimes get modified. If you have an ill-conceived

    data FavoriteFood = Pizza
                      | SesameSpinachPancake
                      | ChanaMasala
    

    and later you learn to like DrunkenNoodles and add it to the list, all your functions that pattern match on the type will need to be expanded. If you've used any _ patterns, you will need to find them manually; the compiler can't help you. If you've matched each thing explicitly, you can turn on -fwarn-incomplete-patterns and GHC will tell you about every spot you've missed.

    0 讨论(0)
提交回复
热议问题