2

どうすればこれを達成できますか?

data SumTerm = 
     St_TotalSum TotalSum
    |St_SumInS SumInS
    |St_SumInT SumInT
    |St_HTerm HTerm

data Monomial  = Monomial {
    mSumTerm :: SumTerm,
    xPower :: Int,
    yPower :: Int,
    coefficient :: Int
    }

newtype Polynomial = Polynomial [ Monomial ]

{- Ok, here I'm lost, VERY lost -}
toMonomial :: (forall {- a which can be in a SumTerm constructor -} ) 
              => a -> SumTerm
toMonomial sum_term = ....

もちろん、この解決策は私の頭に浮かびます:

class ToSumTerm a where
     toSumTerm :: a -> SumTerm 

instance ToSumTerm TotalSum where
     toSumTerm total_sum = St_TotalSum total_sum
instance ToSumTerm SumInS where
     toSumTerm sum_in_s = St_SumInS sum_in_s
...

toMonomial :: ToSumTerm a => a -> Monomial 
toMonomial x = Monomial ( toSumTerm a ) 0 0 1 

ただし、SumTerm のコンストラクターに合わせて自動的にスケーリングされるわけではありません。インスタンスを手で書く必要がない簡単な方法はありますToSumTermか? 言い換えれば、定型的なインスタンス定義を廃棄する (または同等の効果を達成する) ことを可能にする構文はありますか? 解決策がある場合、それはもちろん、GADT などの GHC 拡張機能を意味する可能性があります。

4

1 に答える 1

1

SumTermデータ型は、1 つのレベルのものをラップするだけなので、ここでは何もしていません。存在する可能性も、存在しない可能性もありますSumTerm a。各 MonomialSumTermは、固定された型のセットの 1 つだけを常に含む 1 つだけを保持するため、次の操作を実行できます。

data Monomial a  = Monomial {
    mSumTerm :: a,
    xPower :: Int,
    yPower :: Int,
    coefficient :: Int
    }

もちろん、異質な単項式などのリストを取得すると、再びおかしなことになりますが、最終的に何を望んでいるのかをよりよく理解していない限り、「正しい」答えをより一般的に言うのは難しいです。

于 2013-06-29T18:11:26.157 に答える