我刚刚开始学习Haskell,我使用learnyouahaskell.com作为指南,我使用ghci
作为解释器。我对列表有疑问。在网站上,他们指定功能:
boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]
这仅适用于列表。而
boomBangs x = [ if x < 10 then "BOOM!" else "BANG!" | odd x]
仅适用于单个输入,即
boomBangs 21
boomBangs 7
有没有办法写这个语句,所以无论我是否放
boomBangs [2,5,6,7,1]
或
boomBangs 7
不需要if语句?
答案 0 :(得分:5)
通常,Haskell不允许您随意使用多个不同的实现重载相同的函数名。有一些编程语言可以让你这样做; Haskell不是其中之一。
通常,如果您希望相同的函数针对不同类型的参数(或不同的返回类型)执行不同的操作,则使用类型类。但是,即使这样也不允许你只是任意拥有不同数量或类型的参数;必须有一个模式。
我意识到这只是为了实验目的,但我是dfeuer的评论:boomBangs
应该意味着什么?什么参数类型有意义?好吧,显然在这种情况下boomBangs
是一个简单的示例函数,除了作为示例函数之外,对于任何事情都没有多大意义。 (我不确定你是否已经进入了教程的类型类部分。)
请注意,正如所写,boomBangs
已经多态:它适用于任何类型的整数。它适用于带符号的8位整数,无符号8位整数,带符号的16位整数,无符号16位整数,任意精度整数......所以它适用于相当多的东西。
使列表和非列表工作不是这个函数的非常自然的概括。 (毕竟,这是热潮 - s 。)可能有意义的是将其概括为适用于其他可折叠对象(例如,列表,Maybe
,Either e
)。它可能也适用于任何monad(例如,它似乎稍微调整一下这可能适用于有状态计算或解析器或I / O操作)。但同样,我还不知道是否已经在教程中引入了这些概念中的任何一个。
答案 1 :(得分:5)
是。以不同方式命名您的第二个函数:boomBang
。然后写下boomBangs [2,5,6,7,1]
或boomBang 7
- 不需要if
。
编写代码应该简单而自然,不要让自己变得比以前更难。
现在你有了
boomBangs xs = [b | x <- xs, b <- boomBang x]
删除代码重复,这通常是未充分探索的问题空间的标志。
答案 2 :(得分:2)
您可以使用类型类为不同类型实现不同的行为。例如:
class BoomBang a where
boomBang :: a -> [String]
instance BoomBang Integer where
boomBang x = [if x < 10 then "BOOM" else "BANG" | odd x]
instance BoomBang a => BoomBang [a] where
boomBang xs = xs >>= boomBang
在ghci:
> boomBang 7
["BOOM"]
> boomBang [2,5,6,7,1]
["BOOM","BOOM","BOOM"]