[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