Send Beginners mailing list submissions to
        beginners@haskell.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        beginners-requ...@haskell.org

You can reach the person managing the list at
        beginners-ow...@haskell.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1.  return (user defined type) confusion? (umptious)
   2. Re:  return (user defined type) confusion? (Lorenzo Bolla)


----------------------------------------------------------------------

Message: 1
Date: Thu, 12 Apr 2012 16:08:10 +0100
From: umptious <umpti...@gmail.com>
Subject: [Haskell-beginners] return (user defined type) confusion?
To: beginners@haskell.org
Message-ID:
        <CAE20bNsNmnp2FF_DnTmqhoRKf=dtsm5qakmq_f6ceo-awjx...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"

I'm bashing together a simple command line geometry thing that let's you
create shapes, move them around them, delete and edit them, test for
intersections, etc. The motivation is to get a grip on Haskell IO and how
it interacts with user defined datatypes.  I'm using GHC.

The problem, which I've tried to show as simply as possible in the
abstracted code below, is that something seems to go horribly wrong with
un-boxing (is this the correct terminology?) user defined type X's from
IO(X)'s. In the example below:

- enterCircle makes a Shape using the Circle cstr and boxes it in a return.
And the type checker is happy with the function.

- But when the Shape is un-boxed in mainLoop then Haskell's type system (or
GHC's?) has lost track of its Shapeness. Instead it sees it as a
Pt2->Float. Which makes some sort of sense, but is useless (or at least
needs ugly hacks to overcome) if you want to put your Circle in a List of
Shapes.

- Even worse then the loss of Shapeness is that Haskell is letting me type
enterCircle as returning an IO(Shape) - indeed that's what :t gives me in
GCHI - but then disagrees with this type in mainLoop! This isn't what I was
expecting from the vaunted Haskell type system; can someone explain this
contradiction?

So. Does return fail to wrap up type info about user defined types in
general? Is this correct Haskell behaviour? Or have I done something wrong?

If I haven't done something wrong, is there a standard idiom for overcoming
this? I suppose I could use a show to convert the Circle to a string and
then a read to convert it back in mainLoop's where, but this will mean
uglier branching than I planned (the idea was to have a Map of fns that
return shapes and just one branch in mainLoop to handle every kind of
shape.) And it seems to make something of a nonsense of Haskell's type
system as the entire Shape hierarchy will be reduced to IO(String) for
these operations.






import Data.Map as Map

data Pt2 = Pt2 {x::Float, y::Float} deriving (Show, Read)

data Shape =   Circle   {origin::Pt2, radius::Float}
             | Square   {origin::Pt2, side  ::Float}
             | Rect     {origin::Pt2, other ::Pt2}
               deriving (Show, Read)

enterCircle :: IO(Shape)
enterCircle = return (r) -- needs to rtn io (shape) because will take input
here
       where r = Circle{origin=Pt2{x=1,y=2}, radius=4}


mainLoop :: [Shape] -> IO (String)
mainLoop shapes = do
    putStrLn "?"
    cmd <- getLine
    if cmd=="q"
      then
        return ("done")
      else do
        y <- enterCircle
        mainLoop shapes'
    where shapes' = y : shapes

main = mainLoop []
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://www.haskell.org/pipermail/beginners/attachments/20120412/fa2e2c0f/attachment-0001.htm>

------------------------------

Message: 2
Date: Thu, 12 Apr 2012 16:30:36 +0100
From: Lorenzo Bolla <lbo...@gmail.com>
Subject: Re: [Haskell-beginners] return (user defined type) confusion?
To: umptious <umpti...@gmail.com>
Cc: beginners@haskell.org
Message-ID: <20120412153036.GF25820@dell>
Content-Type: text/plain; charset=us-ascii

It has to do with the scope of "where" in your mainloop.
See comments inline.

On Thu, Apr 12, 2012 at 04:08:10PM +0100, umptious wrote:
> 
> 
> import Data.Map as Map
>    
> data Pt2 = Pt2 {x::Float, y::Float} deriving (Show, Read)
> 
> data Shape =   Circle   {origin::Pt2, radius::Float}
>              | Square   {origin::Pt2, side  ::Float}
>              | Rect     {origin::Pt2, other ::Pt2}
>                deriving (Show, Read)
> 
> enterCircle :: IO(Shape)
> enterCircle = return (r) -- needs to rtn io (shape) because will take input
> here
>        where r = Circle{origin=Pt2{x=1,y=2}, radius=4}
>             
> 
> mainLoop :: [Shape] -> IO (String)           
> mainLoop shapes = do
>     putStrLn "?"
>     cmd <- getLine
>     if cmd=="q"
>       then
>         return ("done")
>       else do
>         y <- enterCircle

This "y" shades the Pt2 accessor "y".

>         mainLoop shapes'
>     where shapes' = y : shapes

This where thinks that "y" is actually the Pt2 accessor "y".

An easy fix would be to rewrite this line as:
>         mainLoop $ y: shapes

Or mess with tabs to get the right scope for "where"...

hth,
L.


-- 
Lorenzo Bolla
http://lbolla.info



------------------------------

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 46, Issue 16
*****************************************

Reply via email to