Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell data type alias naming

I wrote a mathematical Vector module in Haskell.

So I started out with:

data Vector a = Vector !a !a !a deriving (Eq, Show)

Fine—this lets me use any numerical data type I want. The problem is that I don't want to be writing Double and Vector Double everywhere for the simple reason that I shouldn't have to. So I add:

type Scalar = Double
type Vector = Vector Scalar

But of course that second line is wrong, since there are now two declarations of Vector. So what should I change it to? I think to myself, no, I'm going to be writing this all over my code, so I want to leave the type alias simply as Vector. Which means I have to change the data type name. But if I change that, then I feel like I should also change the constructor, which makes everything more confusing. But if it feels awkward making the constructor have the same name as the type alias this way.

Right now I have this:

type Scalar = Double
type Vector = VectorT Scalar

data VectorT a = Vector !a !a !a deriving (Eq, Show)

I picked T arbitrarily (I guess it stands for "type") but I'm not so sure about this. Normally when I document functions I would say -- Calculate the magnitude of a Vector, but with VectorT I feel like I should really be using that type name. So I resort to just referring to them as vectors (not capitalized)—except then I feel like I have to apply this convention to every comment for every data type.

Has anyone been in a similar situation? Can anyone think of a more elegant solution in this case?

like image 968
mk12 Avatar asked Jul 08 '12 05:07

mk12


People also ask

What is a type alias Haskell?

From HaskellWiki. A type synonym is a new name for an existing type. Values of different synonyms of the same type are entirely compatible. In Haskell you can define a type synonym using type : type MyChar = Char.

What is Newtype in Haskell?

In Haskell, the newtype declaration creates a new type from an existing one. For example, natural numbers can be represented by the type Integer using the following declaration: newtype Natural = MakeNatural Integer. This creates an entirely new type, Natural, whose only constructor contains a single Integer.

What is algebraic data type in Haskell?

This is a type where we specify the shape of each of the elements. Wikipedia has a thorough discussion. "Algebraic" refers to the property that an Algebraic Data Type is created by "algebraic" operations. The "algebra" here is "sums" and "products": "sum" is alternation ( A | B , meaning A or B but not both)

What is data Haskell?

In Haskell, you can have many constructors for your data type, separated by a vertical bar | . Each of your constructors then has its own list of data types! So different constructors of the same type can have different underlying data! We refer to a type with multiple constructors as a “sum” type.


2 Answers

One solution to your particular problem would be to have the data type in a different module from the type synonym. That is, have a Math.Vector module which contains the data declaration and some generic functions (that is, functions working for all numeric types). Then, when you actually use Vector Double in your code a lot, just create the type synonym using a qualified import:

import qualified Math.Vector as MV

type Scalar = Double
type Vector = MV.Vector Scalar

I think this makes sense from a code organization standpoint. Particularly, if you've defined your Vector type to work on all numeric types, I expect the functions in that module to also work on all numeric types. The fact that you use Vector Double a lot in some other part of the code should not affect the module where Vector is actually defined. After all, it's completely reasonable to imagine using Vector Int a lot in yet another part of your program.

As an aside, I'm not sure calling it Vector is the best idea. A vector does not necessarily have to have three dimensions, so I would call your data type something like Vector3D. This is actually the name used in some other APIs (like the Java 3D API), so it's probably a good choice.

like image 126
Tikhon Jelvis Avatar answered Oct 12 '22 01:10

Tikhon Jelvis


Is there any specific reason to not just do

data Vector = Vector !Double !Double !Double deriving (Eq, Show)

That seems like the simplest idea to me...

like image 27
MathematicalOrchid Avatar answered Oct 12 '22 03:10

MathematicalOrchid