Sometimes, if one the pattern rules need some special rhs which is made more readable via where
, I end up with something like this
data D = A | B | C
func :: D -> b
func A = special_case
where
special_case = other helper
other = aaaa
helper = bbb
func _ = bla
where the catch-all pattern seems to be so far from the other pattern, because of the lengthy where
. It'd be nice if I could write something like this:
func :: D -> b
func !A = bla -- imaginary syntax
func A = special_case
where
special_case = other helper
other = aaaa
helper = bbb
I don't think it would still be called catch-all, but rather "catch-all-but", but is there any way to do this?
If you don't need to bind anything, you could do something like this:
isA :: D -> Bool
isA A = True
isA _ = False
func :: D -> b
func d | not (isA d) = bla
func A = special_case where ...
(You could alternately implement isn'tA
to avoid the not
. But while I've seen functions like isA
defined every so often, I don't believe I've ever seen an analog of isn'tA
in the wild.)
It might not be obvious to the compiler that this match is complete. You could fix that like this:
type A'sFields = () -- your specific D doesn't have any fields for A,
-- but this pattern is general enough to use for
-- constructors that do
fromA :: D -> Maybe A'sFields
fromA A = Just ()
fromA _ = Nothing
func :: D -> b
func d = case fromA d of
Nothing -> bla
Just () -> special_case where ...