[Haskell-cafe] Over general types are too easy to make.
Tim Docker
tim at dockerz.net
Sun Sep 2 12:13:34 CEST 2012
On 01/09/12 04:00, timothyhobbs at 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
More information about the Haskell-Cafe
mailing list