I have a function:
isItSimple :: Int -> Bool
it gets Int and return Bool.
I need to find first number in [x | x <- [n..], isItSimple x].
Here is my solution:
findIt :: Int -> Int
findIt num
| isItSimple num = num
| otherwise = findIt (num + 1)
Is there any better solution in Haskell?
I need to find first number in [x | x <- [n..], isItSimple x].
How about just like you said.
findIt n = head [ x | x <- [n..], isItSimple x ]
While the other answers work, they're arguably not the most idiomatic way to solve this problem in Haskell. You don't really need any extra imports: a couple of functions from the Prelude will do the trick.
I'd start by creating a list of all of the simple numbers greater than or equal to n
. The function filter :: (a -> Bool) -> [a] -> [a]
makes this easy:
filter isItSimple [n..]
Like [n..]
this is an infinite list, but this isn't a problem since Haskell is lazy and won't evaluate anything until it's needed.
To get what you want you can just take the head of this infinite list:
findIt :: Int -> Int
findIt n = head $ filter isItSimple [n..]
Some people don't like head
since it's a partial function and will raise an exception when it's given an empty list. I personally wouldn't worry about that here, since we know it will never be called on an empty list. It makes me much less uncomfortable than fromJust
, which is also a partial function (it raises an exception when given Nothing
) and in my opinion is always a bad idea.
(And speaking of personal taste, I'd write this as follows:
findIt = head . filter isItSimple . enumFrom
This is an example of pointfree style, which can get convoluted but in this case is very elegant, in my opinion.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With