[Haskell-cafe] Deconstruction

2 views
Skip to first unread message

has...@kudling.de

unread,
Dec 26, 2009, 3:58:44 AM12/26/09
to haskel...@haskell.org
Hi,

while this works:


data Foo a = Foo a

unwrapFoo :: Foo a -> a
unwrapFoo (Foo x) = x


this:


{-# LANGUAGE ExistentialQuantification #-}

class BarLike a where
    doSomething :: a -> Double

data Bar = forall a. BarLike a => Bar a

unwrapBar :: Bar -> a
unwrapBar (Bar x) = x


gives me:


    Couldn't match expected type `a' against inferred type `a1'
      `a' is a rigid type variable bound by
          the type signature for `unwrapBar' at test.hs:8:20
      `a1' is a rigid type variable bound by
           the constructor `Bar' at test.hs:9:11
    In the expression: x
    In the definition of `unwrapBar': unwrapBar (Bar x) = x


How can i deconstruct the enclosed value of type a?

Thanks,
Lenny

Daniel Peebles

unread,
Dec 26, 2009, 4:10:15 AM12/26/09
to has...@kudling.de, haskel...@haskell.org
You can't. The type can't be known, unfortunately.

With a wrapper like that you typically turn on rank-2 polymorphism and apply a function to the value directly:

withBar :: Bar -> (forall a. BarLike a => a -> r) ->r
withBar (Bar x) = f x

Hope this helps,
Dan

_______________________________________________
Haskell-Cafe mailing list
Haskel...@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Miguel Mitrofanov

unread,
Dec 26, 2009, 4:30:40 AM12/26/09
to has...@kudling.de, haskel...@haskell.org

On 26 Dec 2009, at 11:58, has...@kudling.de wrote:

> class BarLike a where
> doSomething :: a -> Double
>
> data Bar = forall a. BarLike a => Bar a
>
> unwrapBar :: Bar -> a
> unwrapBar (Bar x) = x
>

> How can i deconstruct the enclosed value of type a?

You can't write a function with a type that mentions existentially
quantified "a". Period.

But you can deconstruct the enclosed value temporarily:

getSomething :: Bar -> Double
getSomething b =
case b of
Bar a -> doSomething a

Alberto G. Corona

unread,
Dec 26, 2009, 6:49:07 AM12/26/09
to haskell-cafe




Cast uses unsafeCoerce. but well, it´s more elegant ;)


2009/12/26 Miguel Mitrofanov <migue...@yandex.ru>
On 26 Dec 2009, at 12:45, Alberto G. Corona wrote:

You can also make use of Typeable and unsafeCoerce  (Data.Dynamic style)


data Bar = forall a. (BarLike a, Typeable a) => Bar a

unwrapBar :: Bar -> a
unwrapBar (Bar x) = case typeof x== typeof  a of
                                  True -> unsafeCoerce x
                                  False -> error  $ "casting error for type: "++ typeOf a

That's gross. Don't use unsafe functions unless you really need one.


data Bar = forall a. (BarLike a, Typeable a) => Bar a
unwrapBar :: Typeable a => Bar -> a
unwrapBar (Bar x) = fromMaybe (error $ "casting error for type: " ++ show (typeOf x)) $ cast x


 
 




2009/12/26 Miguel Mitrofanov <migue...@yandex.ru>

has...@kudling.de

unread,
Dec 26, 2009, 11:53:21 AM12/26/09
to Miguel Mitrofanov, haskel...@haskell.org
Hi all,

thanks for the insight.

> But you can deconstruct the enclosed value temporarily:
>
> getSomething :: Bar -> Double
> getSomething b =
>      case b of
>          Bar a -> doSomething a

Somehow i fail to apply this.

If you look at

in line 26 i used this for function "adjustToBox", but i still get:

Chlor/Object.hs:33:36:
    Couldn't match expected type `ObjectWrapper'
           against inferred type `a'
      `a' is a rigid type variable bound by
          the constructor `ObjectWrapper' at Chlor/Object.hs:33:12
    In the expression: adjustToBox object
    In a case alternative: ObjectWrapper object -> adjustToBox object
    In the expression:
        case wrapper of { ObjectWrapper object -> adjustToBox object }

:(

Miguel Mitrofanov

unread,
Dec 26, 2009, 12:09:50 PM12/26/09
to has...@kudling.de, haskel...@haskell.org
Your code is equivalent to this:

adjustToBox (ObjectWrapper object) box = adjustToBox object box

but what you've probably intended to write was

adjustToBox (ObjectWrapper object) box = ObjectWrapper (adjustToBox
object box)

It has nothing to do with existentials - it's a simple type mismatch.

has...@kudling.de

unread,
Dec 26, 2009, 12:48:31 PM12/26/09
to Miguel Mitrofanov, haskel...@haskell.org
Oh, you're right, thanks.
I got lost in types and GHC error messages. :/

Miguel Mitrofanov <migue...@yandex.ru> hat am 26. Dezember 2009 um 18:09 geschrieben:
Reply all
Reply to author
Forward
0 new messages