[Haskell-beginners] "downcasting"

Jamie F Olson jamie.f.olson at gmail.com
Tue Mar 26 23:49:11 CET 2013


Andres Löh <andres <at> well-typed.com> writes:

> 
> Hi Emmanuel.
> 
> It's somewhat confusing that in Haskell, data constructors and
> datatypes can have the same name. They're nevertheless different
> beasts. A data constructor is a way to construct values of a datatype,
> or to destruct them via pattern matching. Such constructors themselves
> are *not* types.
> 
> The definition of JSValue looks as follows:
> 
> > data JSValue
> >     = JSNull
> >     | JSBool     !Bool
> >     | JSRational Bool{-as Float?-} !Rational
> >     | JSString   JSString
> >     | JSArray    [JSValue]
> >     | JSObject   (JSObject JSValue)
> >     deriving (Show, Read, Eq, Ord, Typeable)
> 
> So there are six different ways to construct a JSValue, the last one
> is the JSObject constructor. It contains one item which is of *type*
> JSObject JSValue. This time, JSObject refers to a datatype, also
> defined in the library:
> 
> > newtype JSObject e = JSONObject { fromJSObject :: [(String, e)] }
> >     deriving (Eq, Ord, Show, Read, Typeable )
> 
> Now to your functions: if you write
> 
> > getObject :: JSValue -> JSObject JSValue
> > getObject x@(JSObject _) = x
> 
> or
> 
> > getObject :: JSValue -> JSObject JSValue
> > getObject (JSObject x) = JSObject x
> 
> you are writing essentially the identity function, but trying to
> assign a more specific type to the value. This doesn't quite work in
> Haskell. There's no subtyping between different datatypes.
> 
> Instead, what you should do is perform the pattern match once and
> extract its contents:
> 
> > getObject :: JSValue -> JSObject JSValue
> > getObject (JSObject x) = x
> 
> Now you have the stuff that was "inside" the constructor, and isolated
> the point of failure.
> 
> Cheers,
>   Andres
> 

I'm sorry, but I copied exact code and I'm still getting an error:

$:l tst.hs 
[1 of 1] Compiling Main             ( tst.hs, interpreted )
Ok, modules loaded: Main.
$let a = toJSObject [("A","a")]
$a
JSONObject {fromJSObject = [("A","a")]}
$encode a
"{\"A\":\"a\"}"
$getJSObj a

<interactive>:428:10:
    Couldn't match expected type `JSValue'
                with actual type `JSObject [Char]'
    In the first argument of `getJSObj', namely `a'
    In the expression: getJSObj a
    In an equation for `it': it = getJSObj a
$








More information about the Beginners mailing list