Haskell:想要更好的做事方式:value == x ||值 == y ||
Posted
技术标签:
【中文标题】Haskell:想要更好的做事方式:value == x ||值 == y ||【英文标题】:Haskell: Want a better way of doing: value == x || value == y || 【发布时间】:2011-05-16 17:32:13 【问题描述】:我是 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 作为解释器。)
【问题讨论】:
由于您是 Haskell 的新手,从您的回答来看,我认为您应该阅读并了解 Haskell 中的模式匹配。 @Lagerbaer,什么?你是说守卫?这个问题没有很好地利用模式匹配。 也许吧。但是他的第一个解决方案至少可以通过不使用 if ... then 而是使用模式匹配来做得更好。这表明他没有“默认”使用模式匹配,因此这是他应该学习的东西。 是的,这些东西:learnyouahaskell.com/syntax-in-functions 大声笑,谢谢 Rei。我已经找到并阅读了大量的 learnyouahaskell.com,这绝对是我遇到的关于 Haskell 的最佳解释者。 【参考方案1】:在这种情况下,您可以使用 Prelude 中的elem
:
isDigit x = elem x "0123456789"
(记住字符串是 Char 的列表)
或者你可以使用isDigit
from 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
你有它。 foldr
是列表函数的祖父,所以这是在没有显式递归的情况下实现它的“最低级别”方法。以下是您的词汇表的另外两个拼写:
isDigit x = any (x ==) "0123456789"
isDigit x = or [ x == d | d <- "0123456789" ]
如果我不得不猜测最常见的“惯用”拼写,那可能是第一个拼写的变体:
isDigit = (`elem` "0123456789")
一旦您熟悉了 Prelude 中的所有便捷功能,编写这样的代码就是一件轻而易举的事 :-)
【讨论】:
谢谢。这是一个非常全面的答案,正是我想要的:) 为了完整起见,在这种情况下,您还可以使用isDigit x = '0' <= x && x <= '9'
。不过一般来说,你当然需要`elem`
。
如果检查的元素都是连续的,那么foo <= x && x <= bar
总是更好。【参考方案2】:
另一个我没有看到的样式问题是函数
if expr then True else False
等价于简单
expr
【讨论】:
以上是关于Haskell:想要更好的做事方式:value == x ||值 == y ||的主要内容,如果未能解决你的问题,请参考以下文章