I want to define a new abstract data type, which is either a general number construction or a section. How can I do this in Haskell?
My first approach:
data MyMath = MyNum Num
| Div MyMath MyMath
The problem is that the compiler complains about "Num", which is not a data type, but a type class. So my second thought was to solve the problem as follows:
data MyMath = MyNum Int
| MyNum Float
| Div MyMath MyMath
But this will not work, since MyNum is used twice, which is unacceptable, but this approach will not be truly polymorphic. So what is the solution to this problem?
EDIT2 . After (again) reading the answers, I tried using the GADT data constructors. This is some kind of artificial code example:
5 data MyMathExpr a where
6 MyNumExpr :: Num a => a -> MyMathExpr a
7 MyAddExpr :: MyMathExpr b -> MyMathExpr c -> MyMathExpr (b, c)
8 deriving instance Show(MyMathExpr a)
9 deriving instance Eq(MyMathExpr a)
10
11 data MyMathVal a where
12 MyMathVal :: Num a => a -> MyMathVal a
13 deriving instance Show(MyMathVal a)
14 deriving instance Eq(MyMathVal a)
15
16 foo :: MyMathExpr a -> MyMathVal a
17 foo (MyNumExpr num) = MyMathVal num
18 foo (MyAddExpr num1 num2) = MyMathVal (l + r)
19 where (MyMathVal l) = foo num1
20 (MyMathVal r) = foo num2
But something is wrong with line number 18:
test.hs:18:40:
Couldn't match type `b' with `(b, c)'
`b' is a rigid type variable bound by
a pattern with constructor
MyAddExpr :: forall b c.
MyMathExpr b -> MyMathExpr c -> MyMathExpr (b, c),
in an equation for `foo'
at test.hs:18:6
In the first argument of `(+)', namely `l'
In the first argument of `MyMathVal', namely `(l + r)'
In the expression: MyMathVal (l + r)
`c '. , , . ?