Reputation:
I want to create a data type that's either New [Int] or Empty; then I want to use an Int and check if the data type contains the Int. This is probably an extremely simple question but I'm new to creating data types and using them in functions, specifically getting a handle on the syntax; I don't have a grounded understanding of it yet.
data New = New [Int]
| Empty
deriving Show
check :: Int -> New -> Bool
check x ys
| x `elem` New ys = True
| otherwise = False
Upvotes: 0
Views: 97
Reputation: 16105
Even though this is an exercise in using custom data types, I feel like expanding on chepner's question, "What does Empty
provide that New []
does not?" since it was not met with any response: Lists can already be empty, so you could make your check without a custom data type definition:
check :: Int -> [Int] -> Bool
check = elem
With the type that Robin said was isomorphic to your New
type, Maybe
, it would look like:
type New = Maybe [Int]
check :: Int -> New -> Bool
check _ Nothing = False
check x (Just xs) = x `elem` xs
Generally when the standard library offers a data type isomorphic to your current one, you should ask yourself if you want to create your own one. Sometimes it is warranted, but often you will want to use either type
or newtype
and not data
.
With this type, Maybe [Int]
, you must ask yourself why you want to differentiate between Nothing
and Just []
. For example, Nothing
could indicate that the function failed, while Just []
could indicate that it succeeded, but that the (correct) result was empty.
An example of a function where this makes sense is the Change exercise on Exercism:
Correctly determine the fewest number of coins to be given to a customer such that the sum of the coins' value would equal the correct amount of change.
Here Nothing
means that it's not possible to give exact change, and Just []
means that the customer paid the exact amount and needs no change.
If, instead, you'd like some exercises that deal with writing functions for custom data types, see the "W3" exercises on https://github.com/opqdonut/haskell-exercises.
Upvotes: 0
Reputation: 531225
You'll want check
to pattern-match on its New
argument to access the underlying list, if any.
check :: Int -> New -> Bool
check x Empty = False
check x (New ys) = x `elem` ys
One way to collapse the definition a bit is to realize that as far as check
is concerned, the values Empty
and New []
are equivalent.
check :: Int -> New -> Bool
check x ys = x `elem` (case ys of
New ys' -> ys'
Empty -> [])
Upvotes: 3