On 01/09/12 04:00, timothyho...@seznam.cz wrote:
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
I'm curious as to what you find ugly about this. It appears you need to
distinguish between Bars and Frogs, so making them separate types (and
having a 3rd type representing the union) is a natural haskell solution:
data Bar = ..
data Frog = ..
fn1 :: Bar -> ..
fn2 :: Frog -> ..
fn3 :: Either Bar Frog -> ..
Perhaps a more concrete example would better illustrate your problem?
Tim
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe