开发者

Haskell: Want a better way of doing: value == x || value == y ||

开发者 https://www.devze.com 2023-01-27 19:25 出处:网络
I\'m new to Haskell, so am sorry if this is incredibly obvious... I have made the following function (used here as an example to ask about multiple value==something || value==somethingElse checks)

I'm new to Haskell, so am sorry if this is incredibly obvious...

I have made the following function (used here as an example to ask about multiple value==something || value==somethingElse checks) to check if a character is a number:

isDigit :: Char -> Boo开发者_如何学Cl
isDigit x = 
    if 
    x == '0' 
    || x == '1'  
    || x == '2'  
    || x == '3'  
    || x == '4'  
    || x == '5'  
    || x == '6'  
    || x == '7'  
    || x == '8'  
    || x == '9'  
    then True  
    else False

Surely though there must be a neat way to write functions like the one above, so you don't have to repeat the || x == quite so much?

Thank you in advance for your help :)

(If it's relevant: I'm using Hugs as the interpreter.)


In this case you can use elem from the Prelude:

isDigit x = elem x "0123456789"

(Remember that strings are lists of Char)

Or you can use isDigit from Data.Char :-)

Yes, there is a neat way to write almost every repetitive pattern. Here's how to derive it for this one. Start with the list of chars (I'll just do 0-4 for brevity)

"01234"

Map the comparisons:

map (x ==) "01234"
  = [x == '0', x == '1', x == '2', x == '3', x == '4']
  = (x == '0') : (x == '1') : (x == '2') : (x == '3') : (x == '4') : []

Then use foldr. foldr f z is best described as a function that takes a list and replaces : with f and [] with z.

foldr (||) False (map (x ==) "01234")
  = x == '0' || x == '1' || x == '2' || x == '3' || x == '4' || False

And there you have it. foldr is kind of the granddaddy of list functions, so this is the "lowest level" way to do it without explicit recursion. Here are two more spellings for your vocabulary:

isDigit x = any (x ==) "0123456789"
isDigit x = or [ x == d | d <- "0123456789" ]

If I had to guess at the most common "idiomatic" spelling, it would probably be this variant of the first one:

isDigit = (`elem` "0123456789")

Once you get familiar with all the handy functions in the Prelude, writing code like this is a joyous breeze :-)


Another style issue that I didn't see mentioned already is that a function

if expr then True else False

is equivalent to simply

expr
0

精彩评论

暂无评论...
验证码 换一张
取 消