Constraints at construction

If I were to create an object in C#, for instance, I could add code to the constructor that might limit the type further e.g. public class Car { string model; int wheels; public Car ( string model, int no_of_wheels ) { if ( no_of_wheels <= 2 ) { throw new Exception( "a car must have at least 3 wheels"); } this.model = model; this.no_of_wheels = no_of_wheels; } } or I could specify all sorts of things, like the size of an array could only be a certain length, or whatever. Similarly, when creating a column with SQL I'd be able to specify further constraints on the column than just it's type. I don't see how to do this with Haskell and the data keyword. Is there a tutorial someone could point me to, or an explanation of this? Or is it that I have to wrap the creation in an accessor function that checks the inputs first? type Model = String type Wheels = Int data Car = Car Model Wheels car_maker model wheels = if wheels <= 2 then error ... else Car model wheels ? Most of my programming career (if you can call it that:) has been primarily with C# and SQL, and perhaps this heady mixture of OOP and hacked-functional is confusing me! Iain

Hi Iain, The wiki page has quite a nice article: http://www.haskell.org/haskellwiki/Smart_constructors Thanks Neil
-----Original Message----- From: haskell-cafe-bounces@haskell.org [mailto:haskell-cafe-bounces@haskell.org] On Behalf Of Iain Barnett Sent: 09 October 2008 2:03 pm To: haskell-cafe@haskell.org Subject: [Haskell-cafe] Constraints at construction
If I were to create an object in C#, for instance, I could add code to the constructor that might limit the type further e.g.
public class Car { string model; int wheels;
public Car ( string model, int no_of_wheels ) { if ( no_of_wheels <= 2 ) { throw new Exception( "a car must have at least 3 wheels"); }
this.model = model; this.no_of_wheels = no_of_wheels; } }
or I could specify all sorts of things, like the size of an array could only be a certain length, or whatever. Similarly, when creating a column with SQL I'd be able to specify further constraints on the column than just it's type.
I don't see how to do this with Haskell and the data keyword. Is there a tutorial someone could point me to, or an explanation of this? Or is it that I have to wrap the creation in an accessor function that checks the inputs first?
type Model = String type Wheels = Int
data Car = Car Model Wheels
car_maker model wheels = if wheels <= 2 then error ... else Car model wheels
?
Most of my programming career (if you can call it that:) has been primarily with C# and SQL, and perhaps this heady mixture of OOP and hacked-functional is confusing me!
Iain
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
============================================================================== Please access the attached hyperlink for an important electronic communications disclaimer: http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html ==============================================================================

Thankyou, this is exactly what I was looking for. Iain On 9 Oct 2008, at 2:05 pm, Mitchell, Neil wrote:
Hi Iain,
The wiki page has quite a nice article: http://www.haskell.org/haskellwiki/Smart_constructors
Thanks
Neil
-----Original Message----- From: haskell-cafe-bounces@haskell.org [mailto:haskell-cafe-bounces@haskell.org] On Behalf Of Iain Barnett Sent: 09 October 2008 2:03 pm To: haskell-cafe@haskell.org Subject: [Haskell-cafe] Constraints at construction
If I were to create an object in C#, for instance, I could add code to the constructor that might limit the type further e.g.
public class Car { string model; int wheels;
public Car ( string model, int no_of_wheels ) { if ( no_of_wheels <= 2 ) { throw new Exception( "a car must have at least 3 wheels"); }
this.model = model; this.no_of_wheels = no_of_wheels; } }
or I could specify all sorts of things, like the size of an array could only be a certain length, or whatever. Similarly, when creating a column with SQL I'd be able to specify further constraints on the column than just it's type.
I don't see how to do this with Haskell and the data keyword. Is there a tutorial someone could point me to, or an explanation of this? Or is it that I have to wrap the creation in an accessor function that checks the inputs first?
type Model = String type Wheels = Int
data Car = Car Model Wheels
car_maker model wheels = if wheels <= 2 then error ... else Car model wheels
?
Most of my programming career (if you can call it that:) has been primarily with C# and SQL, and perhaps this heady mixture of OOP and hacked-functional is confusing me!
Iain
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
====================================================================== ======== Please access the attached hyperlink for an important electronic communications disclaimer:
http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html ====================================================================== ========

On Thu, Oct 9, 2008 at 3:05 PM, Mitchell, Neil
Hi Iain,
The wiki page has quite a nice article: http://www.haskell.org/haskellwiki/Smart_constructors
Smart constructors are nice but if your module doesn't also export the regular constructor then you can't pattern match against it. It would be cool if there was a way to export constructors from a module, but only for use in pattern matching and not constructing new values. Peace, Bit

On Oct 11, 2008, at 2:54 PM, Bit Connor wrote:
Smart constructors are nice but if your module doesn't also export the regular constructor then you can't pattern match against it.
It would be cool if there was a way to export constructors from a module, but only for use in pattern matching and not constructing new values.
I suppose you could make a new data type to pattern match against. For example, say you have data Foo A B = <hidden constructors> foo :: A -> B -> Foo A B -- smart constructor You could introduce and export data FooView = Foo A B | <other possible deconstructions> fooView :: Foo A B -> FooView A B You could even redefine the smart constructor as foo : FooView A B -> Foo A B ... if you wanted. - Jake

On Thu, 9 Oct 2008, Iain Barnett wrote:
If I were to create an object in C#, for instance, I could add code to the constructor that might limit the type further e.g.
public class Car { string model; int wheels;
public Car ( string model, int no_of_wheels ) { if ( no_of_wheels <= 2 ) { throw new Exception( "a car must have at least 3 wheels"); } this.model = model; this.no_of_wheels = no_of_wheels; } }
I think it is not the right way to handle the number of wheels with an exception. This should be considered an error. http://www.haskell.org/haskellwiki/Error

On 12 Oct 2008, at 9:28 pm, Henning Thielemann wrote:
On Thu, 9 Oct 2008, Iain Barnett wrote:
If I were to create an object in C#, for instance, I could add code to the constructor that might limit the type further e.g.
public class Car { string model; int wheels;
public Car ( string model, int no_of_wheels ) { if ( no_of_wheels <= 2 ) { throw new Exception( "a car must have at least 3 wheels"); } this.model = model; this.no_of_wheels = no_of_wheels; } }
I think it is not the right way to handle the number of wheels with an exception. This should be considered an error. http://www.haskell.org/haskellwiki/Error
Only if you think through the code you're writing - i.e. non idiomatic C# ;) Iain
participants (5)
-
Bit Connor
-
Henning Thielemann
-
Iain Barnett
-
Jake McArthur
-
Mitchell, Neil