[Haskell-cafe] Over general types are too easy to make.

timothyhobbs at seznam.cz timothyhobbs at seznam.cz
Fri Aug 31 20:00:29 CEST 2012


I'd have to say that there is one(and only one) issue in Haskell that bugs 
me to the point where I start to think it's a design flaw:

It's much easier to type things over generally than it is to type things 
correctly.

Say we have a 

>data BadFoo =
> BadBar{
>  badFoo::Int} |
> BadFrog{
>  badFrog::String,
>  badChicken::Int}

This is fine, until we want to write a function that acts on Frogs but not 
on Bars.  The best we can do is throw a runtime error when passed a Bar and 
not a Foo:

>deBadFrog :: BadFoo -> String
>deBadFrog (BadFrog s _) = s
>deBadFrog BadBar{}      = error "Error: This is not a frog."

We cannot type our function such that it only takes Frogs and not Bars.  
This makes what should be a trivial compile time error into a nasty runtime 
one :(

The only solution I have found to this is a rather ugly one:

>data Foo = Bar BarT | Frog FrogT

If I then create new types for each data constructor.

>data FrogT = FrogT{
> frog::String,
> chicken::Int}

>data BarT = BarT{
> foo :: Int}

Then I can type deFrog correctly.

>deFrog :: FrogT -> String
>deFrog (FrogT s _) = s

But it costs us much more code to do it correctly.  I've never seen it done 
correctly.  It's just too ugly to do it right :/ and for no good reason.  It
seems to me, that it was a design mistake to make data constructors and 
types as different entities and this is not something I know how to fix 
easily with the number of lines of Haskell code in existence today :/

>main = do
> frog <- return (Frog (FrogT "Frog" 42))
> print $
>  case frog of
>   (Frog myFrog) -> deFrog myFrog
> badFrog <- return (BadBar 4)
> print $
>  case badFrog of
>   (notAFrog at BadBar{}) -> deBadFrog notAFrog

The ease with which we make bad design choices and write bad code(in this 
particular case) is tragically astounding.

Any suggestions on how the right way could be written more cleanly are very 
welcome!

Timothy Hobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20120831/5c34306e/attachment.htm>


More information about the Haskell-Cafe mailing list