Difference between revisions of "Non-trivial type synonyms"

From HaskellWiki
Jump to navigation Jump to search
(Convert from HaWiki)
 
m (Moving editorial comments to the talk page)
Line 19: Line 19:
   
   
What do you mean by "redefined to be 'id'"? (New to Haskell, though I like it a lot.) Instinctively I dislike the idea of changing things after the code is "stabilized", because code never stabilizes unless because people are afraid to touch it because it's too fragile. I really like the idea of making the type system track units like that... Has anybody worked out the details of a system that would use classes and inheritance to automate the tracking of complex units like Miles/Hour? If I do, I'll probably post it here. --[[User:DanielKnapp]]
 
   
 
==Alternate Miles etc. definitions ==
 
==Alternate Miles etc. definitions ==
Line 38: Line 37:
   
   
One possibly valid reason for removing the constructors and selector may be
 
that they clutters the code too much.
 
(I think restricted type synonyms can sometimes fix this better)
 
 
-- StefanLjungstrand
 
   
 
Structures might be a bit more convenient here.
 
Structures might be a bit more convenient here.
Line 50: Line 44:
 
{- or just use Miles, though this is harder to excise later -}
 
{- or just use Miles, though this is harder to excise later -}
 
</haskell>
 
</haskell>
For tracking more complex units, you may be able to get some of the way by using PhantomTypes or creative use of FunDeps.
+
For tracking more complex units, you may be able to get some of the way by using [[Phantom types]] or creative use of [[Functional dependencies]].
   
   

Revision as of 14:57, 30 September 2006

Make the type system work for you

To avoid Miles/Km , feet/metres goofs:

rather than

	type Miles = Int

use

	newtype Miles = Miles Int

together with

	toMiles :: Int -> Miles
	fromMiles :: Miles -> Int

these can be redefined to be "id" later, after the code is stablized.


Alternate Miles etc. definitions

No need to change things : The functions toMiles and fromMiles is already effectively id !

A "newtype" definition just generates a new type whose implementation is the same as the old one.

The constructor (and possibly selector) really does nothing except coerce between the new type and the old one.

So as undefined is Haskells notation for bottom

	toMiles undefined === undefined

which isn't the case if we use a "data" definition.


Structures might be a bit more convenient here.

  newtype Miles = Miles { fromMiles :: Int }
  toMiles = Miles
      {- or just use Miles, though this is harder to excise later -}

For tracking more complex units, you may be able to get some of the way by using Phantom types or creative use of Functional dependencies.


See also


CategoryIdiom