【发布时间】:2021-10-19 19:54:27
【问题描述】:
我已经声明了以下数据类型
data Poly a = Poly [a]
还有一个类:
class Polynom p where
substitute :: p a -> a -> a
compose :: p a -> p a -> p a
我可以使数据类型成为类的实例:
instance Polynom Poly where
substitute = ...
compose = ...
我还希望Poly 的Ratio 成为同一类的实例;我尝试了许多语法和语言扩展,但没有一个有效;比如:
instance Polynom (Ratio . Poly) where ...
-- error: cannot use (.) there
instance Poly p => Polynom (Ratio (p _)) where ...
-- error: no wildcards allowed
type X a = Ratio (Poly x)
instance Polynom X where ...
-- error: X needs another param
instance Polynom (* -> Ratio (Poly *)) where ...
-- error: wrong kind
我的目标是让substitute 和compose 在Ratio (Poly *) 上工作;例如:
rf1 = Poly [1,2,3] % Poly [4,5,6] :: Ratio (Poly Int)
rf2 = Poly [0,1] % Poly [1,0] :: Ratio (Poly Int)
rf = rf1 `compose` rf2 :: Ratio (Poly Int)
result = substitute rf 10 :: Int
这在 Haskell 中是否可行?如果是这样,我在这里缺少什么语法或语言扩展?
更新
我使用 TypeFamilies 解决了这个问题;正如@leftaroundabout 建议的那样。工作类实例如下所示*:
instance Integral a => Polynom (Ratio (Poly a)) where
type Domain (Ratio (Poly a)) = Ratio a
substitute (n :% d) x = substitute ((%1) <$> n) x
/ substitute ((%1) <$> d) x
compose (n :% d) = substitute ((pure <$> n) % (pure <$> d))
*(其实我也改了不好的名字;但把它们留在这里以免混淆)
【问题讨论】:
-
另见Lambda for type expressions in Haskell?。基础 Haskell 的类型级语言真的很穷。这是故意的,以便更容易实施。
标签: haskell