一般的なNumberまたはDivision構造のいずれかである新しい抽象データ型を定義します。ハスケルでどうしたらいいですか?"data MyMath = MyNum Num"のような抽象データ型を定義する方法は?
私の最初のアプローチでした:
data MyMath = MyNum Num
| Div MyMath MyMath
問題は、コンパイラはデータ型が、型クラスではありません「のNum」文句を言うことです。だから私の第二の考えは、このような問題を解決するために、次のようになります。
data MyMath = MyNum Int
| MyNum Float
| Div MyMath MyMath
しかしMyNumが2回使用されたとして、これは許可されていないいずれかの動作しません、additionalyこのアプローチは本当に多型ではないでしょう。では、この問題の解決策は何ですか?
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)
同じことが `C」のために行きます。私はちょうど私が見ていない愚かな間違いだと思います。あなたは?
私はここに任意のブール値は表示されません。 –
ありがとうございました。この質問を投稿しているうちに、私はすべての必要な場所に行っていた変更を忘れることを忘れました。 – Bastian