Thank you.<br>To be honest I'll have to return to this point later to properly "digest" it because I don't complely get it yet.<br><br>It seems a bit crazy to me to give to the data JSObject the same name as with the newtype JSObject. It is very confusing for me. But I'll get it, it must just sink in.<br>
<br>Thanks a lot, because I would never understand that one on my own...<br><br>Emmanuel<br><br><div class="gmail_quote">On Thu, Oct 25, 2012 at 12:15 AM, Andres Löh <span dir="ltr"><<a href="mailto:andres@well-typed.com" target="_blank">andres@well-typed.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Emmanuel.<br>
<br>
It's somewhat confusing that in Haskell, data constructors and<br>
datatypes can have the same name. They're nevertheless different<br>
beasts. A data constructor is a way to construct values of a datatype,<br>
or to destruct them via pattern matching. Such constructors themselves<br>
are *not* types.<br>
<br>
The definition of JSValue looks as follows:<br>
<br>
> data JSValue<br>
> = JSNull<br>
> | JSBool !Bool<br>
> | JSRational Bool{-as Float?-} !Rational<br>
> | JSString JSString<br>
> | JSArray [JSValue]<br>
> | JSObject (JSObject JSValue)<br>
> deriving (Show, Read, Eq, Ord, Typeable)<br>
<br>
So there are six different ways to construct a JSValue, the last one<br>
is the JSObject constructor. It contains one item which is of *type*<br>
JSObject JSValue. This time, JSObject refers to a datatype, also<br>
defined in the library:<br>
<br>
> newtype JSObject e = JSONObject { fromJSObject :: [(String, e)] }<br>
> deriving (Eq, Ord, Show, Read, Typeable )<br>
<br>
Now to your functions: if you write<br>
<div class="im"><br>
> getObject :: JSValue -> JSObject JSValue<br>
> getObject x@(JSObject _) = x<br>
<br>
</div>or<br>
<div class="im"><br>
> getObject :: JSValue -> JSObject JSValue<br>
> getObject (JSObject x) = JSObject x<br>
<br>
</div>you are writing essentially the identity function, but trying to<br>
assign a more specific type to the value. This doesn't quite work in<br>
Haskell. There's no subtyping between different datatypes.<br>
<br>
Instead, what you should do is perform the pattern match once and<br>
extract its contents:<br>
<div class="im"><br>
> getObject :: JSValue -> JSObject JSValue<br>
</div>> getObject (JSObject x) = x<br>
<br>
Now you have the stuff that was "inside" the constructor, and isolated<br>
the point of failure.<br>
<br>
Cheers,<br>
Andres<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Andres Löh, Haskell Consultant<br>
Well-Typed LLP, <a href="http://www.well-typed.com" target="_blank">http://www.well-typed.com</a><br>
</font></span></blockquote></div><br>