2
4

1 回答 1

3

You can use the first solution if you wrap everything in a constructor which hides the boolean value:

{-# LANGUAGE GADTs, DataKinds, KindSignatures, RankNTypes #-}
data T (x::Bool) where
  Leaf :: Int -> T True
  Rooted :: T True -> T False
  Branch :: T True -> T True -> T True

data TWrap = forall (x :: Bool). TWrap (T x)

[TWrap $ Leaf 1, TWrap $ Rooted (Leaf 2), TWrap $ Branch (Leaf 3) (Branch (Leaf 4) (Leaf 5))]

However, if we are going to have to wrap the type anyways, it's probably better to just go for the more straightforward solution of splitting the type:

data T = Leaf Int | Branch T T
data TWrap = Unrooted T | Rooted T

[Unrooted $ Leaf 1, Rooted $ Leaf 2, Unrooted $ Branch (Leaf 3) (Branch (Leaf 4) (Leaf 5))]

What you are asking for is basically dependent types, which Haskell doesn't have (yet).

于 2017-11-27T12:28:40.147 回答