4

型指定された GADT (GExpr) をハッシュマップに入れたいので、まずそれを対応するモノモーフィック ADT (Expr) に変換します。ハッシュマップから検索すると、モノモーフィック ADT を GADT に変換する際に問題が発生します。

以下は簡易版です。基本的に、「dim」と「gexprOfExpr」の 2 つの関数があり、一度に動作させることができるのは 1 つだけです。私がやろうとしていることは不可能ですか?

{-# OPTIONS_GHC -Wall #-}
{-# Language GADTs #-}

type ListDim = [Int]

data DIM0 = DIM0
data DIM1 = DIM1

class Shape sh where
  shapeOfList :: ListDim -> sh

instance Shape DIM0 where
  shapeOfList _ = DIM0
instance Shape DIM1 where
  shapeOfList _ = DIM1

data Expr = EConst ListDim Double
          | ESum ListDim Int

data GExpr sh where
  GRef :: sh -> Int -> GExpr sh
  GConst :: sh -> Double -> GExpr sh
  GSum :: GExpr DIM1 -> GExpr DIM0  -- GADT, this works for "dim"
--  GSum :: GExpr DIM1 -> GExpr sh -- phantom type, this works for "gexprOfExpr"

dim :: GExpr sh -> sh
dim (GRef sh _) = sh
dim (GConst sh _) = sh
dim (GSum _) = DIM0

gexprOfExpr :: Shape sh => Expr -> GExpr sh
gexprOfExpr (EConst lsh x) = GConst (shapeOfList lsh) x
gexprOfExpr (ESum lsh k) = GSum $ GRef (shapeOfList lsh) k

注: 回復しようとしているタイプはわかっています。それが役立つ場合、これは問題ありません:

gexprOfExpr :: Shape sh => sh -> Expr -> GExpr sh
4

1 に答える 1

3

#haskell の Saizan が答えにつながるヒントを教えてくれました。作業バージョンは次のとおりです。

{-# OPTIONS_GHC -Wall #-}
{-# Language GADTs #-}

import Data.Maybe

type ListDim = [Int]

data DIM0 = DIM0
data DIM1 = DIM1

class Shape sh where
  shapeOfList :: ListDim -> sh
  maybeGExprOfExpr :: Expr -> Maybe (GExpr sh)
  maybeGExprOfExpr _ = Nothing

instance Shape DIM0 where
  shapeOfList _ = DIM0
  maybeGExprOfExpr (ESum lsh k) = Just $ GSum $ GRef (shapeOfList lsh) k
  maybeGExprOfExpr _ = Nothing

instance Shape DIM1 where
  shapeOfList _ = DIM1


data Expr = EConst ListDim Double
          | ESum ListDim Int

data GExpr sh where
  GRef :: sh -> Int -> GExpr sh
  GConst :: sh -> Double -> GExpr sh
  GSum :: GExpr DIM1 -> GExpr DIM0

dim :: GExpr sh -> sh
dim (GRef sh _) = sh
dim (GConst sh _) = sh
dim (GSum _) = DIM0

gexprOfExpr :: Shape sh => Expr -> GExpr sh
gexprOfExpr (EConst lsh x) = GConst (shapeOfList lsh) x
gexprOfExpr e@(ESum _ _) = fromJust $ maybeGExprOfExpr e
于 2012-05-25T00:42:55.310 に答える