[Haskell-cafe] Restrict values in type

Luke Clifton ltclifton at gmail.com
Thu Jan 16 02:07:44 UTC 2014

Well that works wonderfully for parts of the problem.

listOfStrokes = [ Line point point (circle 5)
                , Line point point (rectangle 2 3)
                , Arc point point point (circle 2)
                , Spot point arbitraryPen
                , Spot point (circle 1)
                , Spot point (rectangle 1 1)

*Tmp> :t listOfStrokes
listOfStrokes :: [Stroke]

But how can I extract the information about the PenShape from such a

I can't pattern match (unless there is some language extension I am

case Arc point point point (circle 1) of
    (Arc _ _ _ (circle r)) -> r

<interactive>:67:14: Parse error in pattern: circle

This seems obvious to me because pattern matching works on data
constructors (though I have often found that what I think is obvious is not
always correct...). This would leave me to believe that, because there are
no data constructors for Circle, Rectangle and PenShape that I couldn't
pattern match on it.

I tried to add some functions to the various classes to figure it out, but
that didn't seem to take me anywhere.

On Wed, Jan 15, 2014 at 10:29 PM, Jake McArthur <jake.mcarthur at gmail.com>wrote:

> This is what it should have been. Also, sorry for segmenting my emails.
> data Stroke = Line Point Point (forall p. (Circle p, Rectangle p) => p)
>             | Arc Point Point Point (forall p. Circle p => p)
>             | Spot Point (forall p. PenShape p => p)
> On Jan 15, 2014 9:26 AM, "Jake McArthur" <jake.mcarthur at gmail.com> wrote:
>> Sorry, I used existential types but should have used universal types.
>> On Jan 15, 2014 9:25 AM, "Jake McArthur" <jake.mcarthur at gmail.com> wrote:
>>> You can get some kind of subtyping out of type classes. Then it's just a
>>> matter of making a few different instances so you can do what you want with
>>> them.
>>> class Circle a where
>>>   circle :: Float -> a
>>> class Rectangle a where
>>>   rectangle :: Float -> Float -> a
>>> class (Circle a, Rectangle a) => PenShape a where
>>>   arbitraryPen :: ... -> a
>>> data Stroke = forall p. (Circle p, Rectangle p) => Line Point Point p
>>>             | forall p. Circle p => Arc Point Point Point p
>>>             | forall p. PenShape p => Spot Point p
>>> - Jake
>>> Hi,
>>> I'm quite new to Haskell, and have been loving exploring it. I've always
>>> been a huge fan of languages that let me catch errors at compile time,
>>> finding dynamic languages like Python a nightmare to work in. I'm finding
>>> with Haskell I can take this compile time checking even further than most
>>> static languages and it has gotten me rather excited. So I was wondering if
>>> there is a Haskell way of solving my problem.
>>> I'm trying to represent an image made up of a list of strokes. Strokes
>>> are either lines, arcs or spots, and can be made using different pen shapes.
>>> data Image = Image [Stroke]
>>> data Stroke = Line Point Point PenShape
>>>     | Arc Point Point Point PenShape
>>>     | Spot Point PenShape
>>> data PenShape = Circle Float
>>>     | Rectangle Float Float
>>>     | ArbitraryPen -- Stuff (not relevant)
>>> And this is all great and works.
>>> But now I have a problem. I want to extend this such that Arc strokes
>>> are only allowed to have the Circle pen shape, and Lines are only allowed
>>> to have the Rectangle or Circle pen shapes.
>>> What is the best way of enforcing this in the type system.
>>> I could make more Strokes like LineCircle, LineRectangle, Arc,
>>> PointCircle, PointRectangle, PointArbitrary and get rid of the PenShape
>>> type altogether. But this doesn't really feel good to me (and seems like
>>> the amount of work I have to do is bigger than it needs to be, especially
>>> if I added more basic pen shapes).
>>> I thought about making the different PenShapes different types, using
>>> typeclasses and making Stroke an algebraic data type, but then my strokes
>>> would be of different types, and I wouldn't be able to have a list of
>>> strokes.
>>> I have been looking at DataKinds and GADTs, but I can't quite figure out
>>> if they actually help me here at all.
>>> I'm sure there is a way to do this, I'm just not googling properly.
>>> What I want to write is...
>>> data Image = Image [Stroke]
>>> data Stroke = Line Point Point (Circle or Rectangle)
>>>     | Arc Point Point Point Circle
>>>     | Spot Point PenShape
>>> data PenShape = Circle Float
>>>     | Rectangle Float Float
>>>     | ArbitraryPen -- Stuff (not relevant)
>>> Regards,
>>> Luke
>>> _______________________________________________
>>> Haskell-Cafe mailing list
>>> Haskell-Cafe at haskell.org
>>> http://www.haskell.org/mailman/listinfo/haskell-cafe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20140116/f42a6604/attachment.html>

More information about the Haskell-Cafe mailing list