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

发布于 2024-10-04 17:35:13 字数 584 浏览 3 评论 0原文

我是 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


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



预先感谢您的帮助:)

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

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 -> 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

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.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅浅 2024-10-11 17:35:13

在这种情况下,您可以使用 Prelude 中的 elem:(

isDigit x = elem x "0123456789"

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

或者您可以使用 Data.Char 中的 isDigit :-)

是的,有一种简洁的方法可以编写几乎所有重复的模式。以下是如何导出它。从字符列表开始(为了简洁,我只使用 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') : []

然后使用 foldrfoldr f z 最好的描述是一个函数,它接受一个列表并将 : 替换为 f 并将 [] 替换为 <代码>z。

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

现在你就得到了它。 foldr 是列表函数的鼻祖,因此这是无需显式递归即可实现的“最低级别”方法。这里还有两个适合您的词汇的拼写:

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

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

isDigit = (`elem` "0123456789")

一旦您熟悉了 Prelude 中的所有方便功能,就可以编写如下代码这是一阵欢乐的微风:-)

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 :-)

玩套路吗 2024-10-11 17:35:13

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

if expr then True else False

相当于简单地

expr

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文