Haskell:想要一个更好的方法:value == x || value == y ||

Jon*_*Cox 7 haskell idioms

我是Haskell的新手,很抱歉,如果这非常明显......


我已经做了以下功能(这里用来作为一个例子来询问多个value==something || value==somethingElse检查)来检查一个字符是否是一个数字:


isDigit :: Char -> Bool
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
Run Code Online (Sandbox Code Playgroud)


当然,虽然必须有一个简洁的方法来编写如上所述的函数,所以你不必重复|| x ==这么多吗?



预先感谢您的帮助 :)

(如果相关:我使用Hugs作为翻译.)

luq*_*qui 30

在这种情况下,您可以使用elemPrelude:

isDigit x = elem x "0123456789"
Run Code Online (Sandbox Code Playgroud)

(请记住,字符串是Char的列表)

或者你可以使用isDigitData.Char:-)

是的,几乎每种重复模式都有一种简洁的方法.以下是如何为此推导它.从字符列表开始(为简洁起见我只做0-4)

"01234"
Run Code Online (Sandbox Code Playgroud)

映射比较:

map (x ==) "01234"
  = [x == '0', x == '1', x == '2', x == '3', x == '4']
  = (x == '0') : (x == '1') : (x == '2') : (x == '3') : (x == '4') : []
Run Code Online (Sandbox Code Playgroud)

然后用foldr. foldr f z最好被描述为一个获取列表并替换:f[]使用的函数z.

foldr (||) False (map (x ==) "01234")
  = x == '0' || x == '1' || x == '2' || x == '3' || x == '4' || False
Run Code Online (Sandbox Code Playgroud)

你有它. foldr是一种列表函数的祖父,所以这是没有显式递归的"最低级"方式.这里有两个你的词汇拼写:

isDigit x = any (x ==) "0123456789"
isDigit x = or [ x == d | d <- "0123456789" ]
Run Code Online (Sandbox Code Playgroud)

如果我不得不猜测最常见的"惯用"拼写,它可能是第一个的变体:

isDigit = (`elem` "0123456789")
Run Code Online (Sandbox Code Playgroud)

一旦你熟悉Prelude中所有方便的功能,编写这样的代码是一件快乐的事:-)

  • 为了完整起见,在这种情况下,你也可以使用`isDigit x ='0'<= x && x <='9'`.但总的来说,你当然需要`\`elem \``. (3认同)

小智 6

我没有看到的另一个风格问题是功能

if expr then True else False
Run Code Online (Sandbox Code Playgroud)

相当于简单

expr
Run Code Online (Sandbox Code Playgroud)