Reputation: 164
Some of my data types in Haskell end up having quite a few records, for example
data MyData
= A Int Int String Float Int (Char, Char)
| B Int String Float (Char, String) String
and to check what type it is I end up writing functions like
isA :: MyData -> Bool
isA (A _ _ _ _ _ _) = True
isA _ = False
-- isB and so on
Now this gets cumbersome fairly quickly so I searched how to use derive
or something similar to auto-generate those and I found this. However, the library proposed in that question seems to be out of date due to the introduction of ghc generics and the related generic-deriving library. I've taken a look at these but they seem to be very powerful and I don't quite know where to start.
So my question is: How can you (if possible) get around having to manually write isA
and isB
for MyData
?
Upvotes: 3
Views: 114
Reputation: 116139
Record syntax can be exploited for this.
isA :: MyData -> Bool
isA A{} = True
isA _ = False
This requires no extensions, and works regardless of the number of parameters constructor A
takes.
(That being said, I don't think such functions are that useful in Haskell. Beware of "boolean blindness" -- i.e., of reducing information to booleans when you do not need to.)
Upvotes: 9
Reputation: 164
So one way that circumvents the mindless writing of a lot of type check functions is to use this library (found in the Reddit Ry posted - thanks!).
Example code:
import Data.Generics.Is.TH
-- Cumbersome
printType (A _ _ _ _ _ _) = putStrLn "Is A"
printType (B _ _ _ _ _) = putStrLn "Is B"
-- With library
printType x
| $(is 'A) x = putStrLn "Is A"
| $(is 'B) x = putStrLn "Is B"
Instead of isA
and isB
you would simply write $(is 'A)
or $(is 'B)
which works fine for me.
Upvotes: 0