Я хочу определить новый абстрактный тип данных, который является либо общей конструкцией числа, либо разделом. Как мне это сделать в Haskell?Как определить абстрактный тип данных, например «данные MyMath = MyNum Num»?
Мой первый подход:
data MyMath = MyNum Num
| Div MyMath MyMath
Проблема заключается в том, что компилятор жалуется на «Num», который не является типом данных, но класс типа. Так что моя вторая мысль была бы решить эту проблему следующим образом:
data MyMath = MyNum Int
| MyNum Float
| Div MyMath MyMath
Но это не будет работать либо как используются тупит дважды, не допускаются, дополнительно этот подход не будет действительно полиморфным. Итак, каково решение этой проблемы?
EDIT2: После (снова) чтения ответов я попытался использовать конструкторы данных GADT. Это некоторый искусственный пример кода:
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
Но что-то не так с линии номер 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)
То же самое относится и к `с». Думаю, это глупая ошибка, которую я просто не вижу. Вы?
Я не вижу никаких логических значений здесь. –
Спасибо, Дон, отправляя этот вопрос, я забыл приспособить изменения, которые я делал тем временем, ко всем необходимым местам - теперь это должно быть яснее. – Bastian