I am just starting to learn Haskell and I am using learnyouahaskell.com as the guide, and I am using ghci
as interpreter. I have a question regarding lists. On the website they specify the function:
boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]
This works only for lists. Whereas
boomBangs x = [ if x < 10 then "BOOM!" else "BANG!" | odd x]
Only works for single inputs, ie
boomBangs 21
boomBangs 7
Is there a way to write this statement so that it doesn't matter whether I put
boomBangs [2,5,6,7,1]
or
boomBangs 7
without the need of an if statement?
In general, Haskell does not allow you to just arbitrarily overload the same function name with multiple distinct implementations. There are programming languages that let you do this; Haskell is not one of them.
In general, if you want the same function to do something different for different types of arguments (or different return type, for that matter), you use type classes. However, even this does not allow you to just arbitrarily have different numbers or types of arguments; there must be a pattern to it.
I realise this is only for experimentation purposes, but I second the comment by dfeuer: what is boomBangs
supposed to mean ? What argument types does it make sense for? Well, obviously in this case boomBangs
is a trivial example function, and doesn't really make much sense for anything except as an example function. (I'm not sure if you've even got to the type class part of the tutorial yet.)
Notice that, as written, boomBangs
is already polymorphic: It will work for any type of integer. It works for signed 8-bit integers, unsigned 8-bit integers, signed 16-bit integers, unsigned 16-bit integers, arbitrary-precision integers... So it's working for quite a bit of stuff.
Making it work for lists and non-lists isn't a very natural generalisation of this function. (It is boom-bang , after all.) What might make sense is to generalise it to work for other foldable objects (eg, list, Maybe
, Either e
). 毕竟。)什么可能是有意义的是推广它为其他可折叠的对象(例如,列表,工作Maybe
, Either e
)。 It might also make sense for it to work on any monad (eg, it looks like a slight tweak of this might work for stateful computations or parsers or I/O actions). But again, I don't know if either of those concepts have been introduced in the tutorial yet.
Yes. Name your second function differently: boomBang
. Then write boomBangs [2,5,6,7,1]
or boomBang 7
-- no if
required.
Writing code should be easy and natural, don't make it harder on yourself than it has to be.
Now you have
boomBangs xs = [b | x <- xs, b <- boomBang x]
removing the code duplication, which is usually a sign of underexplored problem space.
You may implement different behaviors for different types using type classes. For example:
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
In ghci:
> boomBang 7
["BOOM"]
> boomBang [2,5,6,7,1]
["BOOM","BOOM","BOOM"]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.