Haskell 刮一些样板

Haskell 刮一些样板,haskell,Haskell,我怎样才能做到这一点 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 Pol

我怎样才能做到这一点

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
?换句话说,是否有一些语法允许废弃样板实例定义(或实现等效效果)?如果有解决方案,它当然可以暗示任何GHC扩展,比如GADT。

您的
SumTerm
数据类型在这里什么都不做,因为它只是包装了一个层次的内容。它也可能是
SumTerm a
,或者根本不存在。由于每个单项式只包含一个
SumTerm
,它总是只包含一组固定类型中的一个,因此您可以执行以下操作

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

现在,当然,一旦你有了一个异类单项式或类似的列表,事情又变得有趣了,但很难说“正确”的答案一般是什么,除非我对你最终想要什么有更大的了解。

你的代码中有没有一部分需要在
SumTerm
上进行模式匹配?如果没有,我认为类型类和ADT版本都应该随着案例的数量线性扩展。@missingno我同意:如果我幸运的话,一切都会线性扩展。。。但出于好奇,我想知道是否有更好的方法。顺便问一下,你说的ADT和(?)类型类是什么意思?小建议是让typeclass
ToMonomial
ToMonomial::a->Monomial
作为其成员。谢谢你的回答。我的意图是将列表中“单项式”的几个异构实例组合起来,形成一个多项式。正如您所注意到的,SumTerm数据类型只是隐藏了具体类型。我的问题可以重新表述为“是否有一些语法允许废弃样板实例定义?”。。。相应地进行了编辑。@dsign您是否单独使用了
TotalSum
SumInS等?另一个选项是将它们内联到要开始的
SumTerm`类型中。。。