Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

to overload a data type or to use a similar one?

Tags:

haskell

This is more of a question about a programming style and common practices. But I feel that it does not fit into the code review forum...

My program parses regular expressions and processes them. A regular expression can have the usual elements (Kleene closure, concatenation, etc) and it also can have references to other regular expressions by their names, like macros:

data Regex a = Epsilon
             | Literal a
             | Ranges [(a, a)]
             | Ref String
             | Then (Regex a) (Regex a)
             | Or (Regex a) (Regex a)
             | Star (Regex a)

After I process a regular expression and resolve all macro references, and convert Literal elements to Range elements (this is needed for my purposes), I end up with a type that cannot and must not have Ref and Literal, so in my functions that work with it I do something like:

foo (Literal _) = error "unexpected literal"
foo (Ref _)     = error "unexpected reference"
foo (Epsilon)   = ...
foo (Star x)    = ...
...

This looks ugly to me because it does runtime checks instead of checks during compilation. Not a very haskell kind of approach.

So maybe I can introduce another data type which is very similar to the original one and use that?

data RegexSimple a = Epsilon2
                   | Ranges2 [(a, a)]
                   | Then2 (Regex a) (Regex a)
                   | Or2 (Regex a) (Regex a)
                   | Star2 (Regex a)

That would work, but here I have a lot of duplication and also the nice and descriptive names of constructors are taken now and I need to invent new ones...

What would the experts do here? I want to learn : )

like image 650
akonsu Avatar asked Aug 15 '15 19:08

akonsu


People also ask

What methods are called overloaded?

In Java, two or more methods may have the same name if they differ in parameters (different number of parameters, different types of parameters, or both). These methods are called overloaded methods and this feature is called method overloading.

What are the two types of overloading?

There are mainly two types of overloading, i.e. function overloading and operator overloading. Function overloading improves the code readability, thus keeping the same name for the same action. Operator overloading allows redefining the existing functionality of operators, thus by giving special meaning to them.

Can we overload method with same return type?

We can not define more than one method with the same name, Order, and type of the arguments. It would be a compiler error. The compiler does not consider the return type while differentiating the overloaded method. But you cannot declare two methods with the same signature and different return types.

Why would you overload a method?

Benefits of using Method Overloading Method overloading increases the readability of the program. This provides flexibility to programmers so that they can call the same method for different types of data. This makes the code look clean.


1 Answers

I don't know what the rest of your code looks like, so this solution may require you to rethink certain aspects, but the most "haskell-ish" solution to this problem would probably be to use GADTs and phantom types. Together, they basically allow you to create arbitrary subtypes for more flexible type safety. You would redefine your types like so.

{-# LANGUAGE GADTs #-}

data Literal
data Ref
data Rangeable

data Regex t a where
         Epsilon :: Regex Rangeable a
         Literal :: a -> Regex Literal a
         Ranges  :: [(a, a)] -> Regex Rangeable a
         Ref     :: String -> Regex Ref a
         Then    :: Regex t' a -> Regex t' a -> Regex Rangeable a
         Or      :: Regex t' a -> Regex t' a -> Regex Rangeable a
         Star    :: Regex t' a -> Regex Rangeable

Then you can define

foo :: Regex Rangeable a
foo (Epsilon)  = ...
foo s@(Star a) = ...

Now, statements like foo $ Literal 'c' will fail compile-time type-checks.

like image 68
Kwarrtz Avatar answered Nov 07 '22 16:11

Kwarrtz