【发布时间】:2013-06-30 02:21:43
【问题描述】:
我怎样才能做到这一点?
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进行模式匹配的部分?如果没有,我认为类型类和 ADT 版本最终都应该随着案例数量线性扩展。 -
@missingno 我同意:如果我很幸运,一切都会线性扩展......但只是为了好奇,我想知道是否有更好的方法。顺便问一下,ADT vs(?) 类型类是什么意思?
-
次要建议是将类型类
ToMonomial和toMonomial :: a -> Monomial作为其成员。
标签: haskell