私は特定のデータコンストラクタを別のデータコンストラクタの内部に入れることはできませんが、両方とも同じ型を与えることはできますか?
[Leaf 1, Rooted (Leaf 2), Branch (Leaf 3) (Branch (Leaf 4) (Leaf 5))]
なく
[Leaf 1, Rooted (Leaf 2), Branch (Rooted (Leaf 3)) (Branch (Leaf 4) (Leaf 5))]
すなわちすることができますHaskellではタイプT
をしたいのですが。 Rooted
を除くT
のすべてのコンストラクタは、Branch
の最初の引数または2番目の引数に現れることがあります(完全なコードにはさらにいくつかのコンストラクタがあります)。
私たちはBranch (Rooted …) …
を行うことはできません保証しますが、またそれは、異なる種類([T True, T False]
)のリストになりますので、我々は[Rooted …, One …]
を行うことができないことを意味
{-# LANGUAGE GADTs #-}
data T (x::Bool) where
Leaf :: Int -> T True
Rooted :: T True -> T False
Branch :: T True -> T True -> T True
のようなものを試してみました。
私は
{-# LANGUAGE GADTs, DataKinds, KindSignatures #-}
data T where
Leaf :: Int -> T
Rooted :: T -> T
Branch :: UnRooted a => a -> a -> T
class UnRooted a
instance UnRooted Leaf
instance UnRooted Branch
を行うことができます願って、DataKindsに見えたが、その後、GHC(7.10.3)はData constructor ‘Leaf’ comes from an un-promotable type ‘T’
を与えます。
ハスケルでこれを行う方法はありますか?あなたはブール値を隠し、コンストラクタ内のすべてを包む場合
同じ(同種の)リストに入れる場合は、同じタイプをルートと非ルートに付ける必要があります。しかし、同じ型を持つ場合は、他のものをサブツリーに置き換えることができます。このように、これは不可能です。おそらく、あなたの最初の試みを実体ラッパーにラップして、その型のブール値を取り除くことは可能でしょうか?または合計型を使用しますか?または、GADTを使用せずに、ルートを独自の型にします(まだ和またはラッパーを使用します)。 – chi
あなたはこれを望む理由を説明できますか?つまり、 'Rooted'コンストラクタは何のためにあるのでしょうか? – MathematicalOrchid
パターンマッチャーです。私はかなりコンパクトな構文で簡単なリストとして式を書くことができるようにしたいと思います。 'Branch'は実際には2つの式を結合する演算子のセットです。 'Rooted'は"このパターンが前/次のパターンのすぐ隣に現れる必要はありません "といったようなラッパーです。しかし、この種のタイプをクリーン/シンプルな方法で定義するのは難しいようです。だから私は別のアプローチを見つけるべきだと思います。 – unhammer