
Below is some code that is produces information about the *types* used for measuring (e.g. metres). The following evaluation returns 1.00 which the convert factor for metres. convertFactorToBaseUnit (unit (LengthInMetres 7)) . The next evaluation returns the type, Metre, of data being measured unit (LengthInMetres 7) Using the particular definitions below is it possible to make an instance of MetricDescription for centimetres? I have an error on the defintion of the unit function in the definition of the MetricDescription instance. As far as possible I would like to retain the data types and class structures. Thanks, Pat class (Unit unit) => MetricDescription description unit | description -> unit where unit :: description -> unit valueInUnit :: description -> Double valueInBaseUnit :: description -> Double valueInBaseUnit d = (convertFactorToBaseUnit(unit d)) * (valueInUnit d) data Metre = Metre deriving Show data Centimetre = Centimetre deriving Show -- Each member of the Unit class has one operator convertFactorToBaseUnit -- that takes a measurement unit (say metre) and returns a conversion factor for that unit of measurement class Unit unit where convertFactorToBaseUnit :: unit -> Double -- An instance for metres, where the convert factor is 1.0 instance Unit Metre where convertFactorToBaseUnit Metre = 1.0 -- An instance for metres, where the convert factor is 0.1 instance Unit Centimetre where convertFactorToBaseUnit Centimetre = 0.1 data LengthInMetres = LengthInMetres Double deriving Show data LengthInCentimetres = LengthInCentimetres Double deriving Show -- This seems fine instance MetricDescription LengthInMetres Metre where valueInUnit (LengthInMetres d) = d unit l = Metre -- This is the instance that I cannot get to work -- The unit 2 function seems to be the problem. -- instance MetricDescription LengthInCentimetres Centimetre where -- valueInUnit (LengthInCentimetres d) = d -- unit 2 = Centimetre This message has been scanned for content and viruses by the DIT Information Services E-Mail Scanning Service, and is believed to be clean. http://www.dit.ie

Hi, Your definition of 'unit' in the instance MetricDescription LengthInCentimetres Centimetre is not well-typed. Maybe you want to write either unit (LengthInCentimitres 2.0) = Centimetre -- (pattern match fail for all (LengthInCentimetres l), l /= 2.0) or unit l = Centimetre -- i.e. unit = const Centimetre as in the instance for Metre Steffen On 01/28/2011 12:42 PM, Patrick Browne wrote:
Below is some code that is produces information about the *types* used for measuring (e.g. metres). The following evaluation returns 1.00 which the convert factor for metres.
convertFactorToBaseUnit (unit (LengthInMetres 7)) . The next evaluation returns the type, Metre, of data being measured unit (LengthInMetres 7)
Using the particular definitions below is it possible to make an instance of MetricDescription for centimetres? I have an error on the defintion of the unit function in the definition of the MetricDescription instance. As far as possible I would like to retain the data types and class structures.
Thanks, Pat
class (Unit unit) => MetricDescription description unit | description -> unit where unit :: description -> unit valueInUnit :: description -> Double valueInBaseUnit :: description -> Double valueInBaseUnit d = (convertFactorToBaseUnit(unit d)) * (valueInUnit d)
data Metre = Metre deriving Show data Centimetre = Centimetre deriving Show
-- Each member of the Unit class has one operator convertFactorToBaseUnit -- that takes a measurement unit (say metre) and returns a conversion factor for that unit of measurement class Unit unit where convertFactorToBaseUnit :: unit -> Double
-- An instance for metres, where the convert factor is 1.0 instance Unit Metre where convertFactorToBaseUnit Metre = 1.0
-- An instance for metres, where the convert factor is 0.1 instance Unit Centimetre where convertFactorToBaseUnit Centimetre = 0.1
data LengthInMetres = LengthInMetres Double deriving Show data LengthInCentimetres = LengthInCentimetres Double deriving Show
-- This seems fine instance MetricDescription LengthInMetres Metre where valueInUnit (LengthInMetres d) = d unit l = Metre
-- This is the instance that I cannot get to work -- The unit 2 function seems to be the problem. -- instance MetricDescription LengthInCentimetres Centimetre where -- valueInUnit (LengthInCentimetres d) = d -- unit 2 = Centimetre
This message has been scanned for content and viruses by the DIT Information Services E-Mail Scanning Service, and is believed to be clean. http://www.dit.ie
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Steffen, Thank you very much for taking the time to solve my problem. Pat On 29/01/2011 12:18, Steffen Schuldenzucker wrote:
unit l = Centimetre
This message has been scanned for content and viruses by the DIT Information Services E-Mail Scanning Service, and is believed to be clean. http://www.dit.ie

Patrick Browne schrieb:
Below is some code that is produces information about the *types* used for measuring (e.g. metres). The following evaluation returns 1.00 which the convert factor for metres.
convertFactorToBaseUnit (unit (LengthInMetres 7)) . The next evaluation returns the type, Metre, of data being measured unit (LengthInMetres 7)
Is there a reason why you use an individual type for every unit? The existing implementations of typed physical units only encode the physical dimension in types and leave the unit factors to the value level. I found this to be the most natural way. http://www.haskell.org/haskellwiki/Physical_units

On 29/01/2011 20:56, Henning Thielemann wrote:
Is there a reason why you use an individual type for every unit? The existing implementations of typed physical units only encode the physical dimension in types and leave the unit factors to the value level. I found this to be the most natural way.
I am studying type classes using examples from the literature [1]. There is no particular intension to implement anything. I am confused about the unit function in the code below. My understanding is: The signature of the unit function is defined in the MetricDescription class. Any valid instantce of MetricDescription will respect the functional dependency (FD): The FD | description -> unit is exactly the signature of the unit function. My confusions I do not understand the definitions of unit in the instances. I do not know how the constant 1 can be equated with a *type*, Where did 1 come from? I do not know how the constant 1 can be equated with *two distinct* definitions of the function uint and still produce the following correct results Ok, modules loaded: A. *A> unit (LengthInMetres 7) Metre *A> unit (LengthInCentimetres 7) Centimetre *A> [1] http://ifgi.uni-muenster.de/~lutzm/odbase04_schade_et_al.pdf ====================================================================== module A where -- Each member of the Unit class has one operator convertFactorToBaseUnit -- that takes a measurement unit (say metre) and returns a conversion factor for that unit of measurement class Unit unit where convertFactorToBaseUnit :: unit -> Double class (Unit unit) => MetricDescription description unit | description -> unit where unit :: description -> unit valueInUnit :: description -> Double valueInBaseUnit :: description -> Double valueInBaseUnit d = (convertFactorToBaseUnit(unit d)) * (valueInUnit d) data Dog = Dog deriving Show data Metre = Metre deriving Show data Centimetre = Centimetre deriving Show -- An instance for metres, where the convert factor is 1.0 instance Unit Metre where convertFactorToBaseUnit Metre = 1.0 -- An instance for centimetres, where the convert factor is 0.1 instance Unit Centimetre where convertFactorToBaseUnit Centimetre = 0.1 data LengthInMetres = LengthInMetres Double deriving Show data LengthInCentimetres = LengthInCentimetres Double deriving Show instance MetricDescription LengthInMetres Metre where valueInUnit (LengthInMetres d) = d unit l = Metre instance MetricDescription LengthInCentimetres Centimetre where valueInUnit (LengthInCentimetres d) = d unit l = Centimetre This message has been scanned for content and viruses by the DIT Information Services E-Mail Scanning Service, and is believed to be clean. http://www.dit.ie

Patrick Browne schrieb:
On 29/01/2011 20:56, Henning Thielemann wrote:
Is there a reason why you use an individual type for every unit? The existing implementations of typed physical units only encode the physical dimension in types and leave the unit factors to the value level. I found this to be the most natural way.
I am studying type classes using examples from the literature [1]. There is no particular intension to implement anything.
I am confused about the unit function in the code below. My understanding is: The signature of the unit function is defined in the MetricDescription class. Any valid instantce of MetricDescription will respect the functional dependency (FD): The FD | description -> unit is exactly the signature of the unit function.
My confusions I do not understand the definitions of unit in the instances. I do not know how the constant 1 can be equated with a *type*, Where did 1 come from?
I do not see a constant 1 that is equated with a type.
I do not know how the constant 1 can be equated with *two distinct* definitions of the function uint and still produce the following correct results
Where is the constant 1 equated with two distinct definitions of 'unit'?
Ok, modules loaded: A. *A> unit (LengthInMetres 7) Metre *A> unit (LengthInCentimetres 7) Centimetre *A>
'unit' is a method of the class MetricDescription. The particular implementation of 'unit' is chosen by the compiler according to the type of the actual parameter and result of 'unit'.
module A where
-- Each member of the Unit class has one operator convertFactorToBaseUnit -- that takes a measurement unit (say metre) and returns a conversion factor for that unit of measurement class Unit unit where convertFactorToBaseUnit :: unit -> Double
class (Unit unit) => MetricDescription description unit | description -> unit where unit :: description -> unit valueInUnit :: description -> Double valueInBaseUnit :: description -> Double
Since valueInUnit and valueInBaseUnit do not need the 'unit' type, I would put them in a separate class.
valueInBaseUnit d = (convertFactorToBaseUnit(unit d)) * (valueInUnit d)
data Dog = Dog deriving Show data Metre = Metre deriving Show data Centimetre = Centimetre deriving Show
-- An instance for metres, where the convert factor is 1.0 instance Unit Metre where convertFactorToBaseUnit Metre = 1.0
-- An instance for centimetres, where the convert factor is 0.1 instance Unit Centimetre where convertFactorToBaseUnit Centimetre = 0.1
I assumed that 0.01m = 1cm
data LengthInMetres = LengthInMetres Double deriving Show data LengthInCentimetres = LengthInCentimetres Double deriving Show
instance MetricDescription LengthInMetres Metre where valueInUnit (LengthInMetres d) = d unit l = Metre
If you enable compiler warnings, then the compiler will warn you, that 'l' is not used. You can also write unit _ = Metre
instance MetricDescription LengthInCentimetres Centimetre where valueInUnit (LengthInCentimetres d) = d unit l = Centimetre

On 30/01/2011 19:43, Henning Thielemann wrote:
I do not see a constant 1 that is equated with a type.
This is due to my misunderstanding of Haskell. After your comments my understanding of the unit function is as follows: 1) In the instance below the argument for unit must have type LengthInMetres
instance MetricDescription LengthInMetres Metre where
valueInUnit (LengthInMetres d) = d unit l = Metre
2) The constant 1 on the LHS can be replaced _ because it is the fact that unit is defined in this instance the determines the return value. 3) The RHS is not a type but a constructor. 4) The compiler ensures the correct unit function is called for either MetricDescription instances. Thanks for your help, Pat This message has been scanned for content and viruses by the DIT Information Services E-Mail Scanning Service, and is believed to be clean. http://www.dit.ie

Patrick Browne schrieb:
On 30/01/2011 19:43, Henning Thielemann wrote:
I do not see a constant 1 that is equated with a type.
This is due to my misunderstanding of Haskell. After your comments my understanding of the unit function is as follows:
1) In the instance below the argument for unit must have type LengthInMetres
instance MetricDescription LengthInMetres Metre where
valueInUnit (LengthInMetres d) = d unit l = Metre
2) The constant 1 on the LHS can be replaced _ because it is the fact that unit is defined in this instance the determines the return value.
Btw. the parameter of 'unit' is a lower-case "L" not a One.
3) The RHS is not a type but a constructor.
right

Patrick,
I find Andrew Frank's work on axiomatic specifications of GIS systems
-- which the paper you cite is built on -- very confusing, or indeed,
confused. They have a bunch of example like
data Car = Car Color
class Car a where
carColor :: a -> Color
instance Car Car where
carColor (Car c _) = c
as if there is some kind of special logical interpretation of having a
class Car in addition to the data type Car. As far as I remember, they
interpret type classes as axioms. After reading it, without being an
expert in either GIS or a logician, I came away thinking that they
were mixing some very abstract ideas from object-oriented languages
into Haskell. I find the presentations of type classes by e.g. Mark
Jones, and the links between functional programming and logic from
either the Curry-Howard correspondence or HOL-style reasoning (for
instance, see the HOL light manual), somewhat crisper.
Tom
On Sun, Jan 30, 2011 at 10:27 AM, Patrick Browne
On 29/01/2011 20:56, Henning Thielemann wrote:
Is there a reason why you use an individual type for every unit? The existing implementations of typed physical units only encode the physical dimension in types and leave the unit factors to the value level. I found this to be the most natural way.
I am studying type classes using examples from the literature [1]. There is no particular intension to implement anything.
I am confused about the unit function in the code below. My understanding is: The signature of the unit function is defined in the MetricDescription class. Any valid instantce of MetricDescription will respect the functional dependency (FD): The FD | description -> unit is exactly the signature of the unit function.
My confusions I do not understand the definitions of unit in the instances. I do not know how the constant 1 can be equated with a *type*, Where did 1 come from? I do not know how the constant 1 can be equated with *two distinct* definitions of the function uint and still produce the following correct results
Ok, modules loaded: A. *A> unit (LengthInMetres 7) Metre *A> unit (LengthInCentimetres 7) Centimetre *A>
[1] http://ifgi.uni-muenster.de/~lutzm/odbase04_schade_et_al.pdf
======================================================================
module A where
-- Each member of the Unit class has one operator convertFactorToBaseUnit -- that takes a measurement unit (say metre) and returns a conversion factor for that unit of measurement class Unit unit where convertFactorToBaseUnit :: unit -> Double
class (Unit unit) => MetricDescription description unit | description -> unit where unit :: description -> unit valueInUnit :: description -> Double valueInBaseUnit :: description -> Double valueInBaseUnit d = (convertFactorToBaseUnit(unit d)) * (valueInUnit d)
data Dog = Dog deriving Show data Metre = Metre deriving Show data Centimetre = Centimetre deriving Show
-- An instance for metres, where the convert factor is 1.0 instance Unit Metre where convertFactorToBaseUnit Metre = 1.0
-- An instance for centimetres, where the convert factor is 0.1 instance Unit Centimetre where convertFactorToBaseUnit Centimetre = 0.1
data LengthInMetres = LengthInMetres Double deriving Show data LengthInCentimetres = LengthInCentimetres Double deriving Show
instance MetricDescription LengthInMetres Metre where valueInUnit (LengthInMetres d) = d unit l = Metre
instance MetricDescription LengthInCentimetres Centimetre where valueInUnit (LengthInCentimetres d) = d unit l = Centimetre
This message has been scanned for content and viruses by the DIT Information Services E-Mail Scanning Service, and is believed to be clean. http://www.dit.ie
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (4)
-
Henning Thielemann
-
Patrick Browne
-
Steffen Schuldenzucker
-
Tom Nielsen