代码之家  ›  专栏  ›  技术社区  ›  Jon Cox

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

  •  7
  • Jon Cox  · 技术社区  · 15 年前

    我是哈斯克尔的新朋友,所以很抱歉如果这是非常明显的。。。


    我做了以下函数(这里作为一个例子来询问 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
    


    当然,虽然必须有一种简洁的方法来编写上面这样的函数,所以您不必重复 || x == 相当多?



    提前感谢您的帮助:)

    (如果相关的话:我用拥抱作为翻译。)

    2 回复  |  直到 15 年前
        1
  •  30
  •   luqui    15 年前

    在这种情况下,您可以使用 elem 前奏曲:

    isDigit x = elem x "0123456789"
    

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

    或者你可以用 isDigit Data.Char :-)

    是的,有一种简洁的方法可以写出几乎所有重复的模式。这里是如何为这个推导出来的。从字符列表开始(为了简洁起见,我只做0-4)

    "01234"
    

    映射比较:

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

    然后使用 foldr . foldr f z 最好描述为一个函数,它接受一个列表并替换 : 具有 f [] 具有 z .

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

    你拿到了。 福尔德 是列表函数的祖宗,所以这是不使用显式递归的“最低级别”方法。这里还有两个单词拼写:

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

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

    isDigit = (`elem` "0123456789")
    

    一旦你熟悉了前奏曲中所有方便的函数,编写这样的代码就轻而易举了:-)

        2
  •  6
  •   Ketil    15 年前

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

    if expr then True else False
    

    相当于

    expr