我想为可以交叉在一起的几何对象定义一个类型类:
class Intersect a b c | a b -> c where
intersect :: a -> b -> c
-- Language extensions: -XMultiParamTypeClasses, -XFunctionalDependencies
这个想法是要有一个通用的交集函数,可以处理不同类型的对象。可以想象这样的情况
instance Intersect Line Plane (Maybe Point) where
...
instance Intersect Plane Plane (Maybe Line) where
...
但我也想声明交集是可交换的:
instance (Intersect a b c) => Intersect b a c where
intersect x y = intersect y x
-- Language extensions: -XUndecidableInstances
问题是,每当我求值intersect x y
而未先定义形式的实例时Intersect a b c
(其中a
是的类型x
和b
是的类型)y
,程序都会进入无限循环,这大概是由有关可交换性的递归实例声明引起的。理想情况下,我希望intersect Egg Bacon
无法进行类型检查,因为没有定义此类实例,而不是使我陷入无限循环。我该如何实施?
听起来像您可以尝试使用类型家族来做的事情。您可能会在堆栈溢出时得到更好的响应。
—
本杰明·霍奇森
这是有关强制执行可交换性的monad的博客文章,也许可以提供帮助:gelisam.blogspot.ca/2013/07/the-commutative-monad.html
—
DanielDíazCarrete 2015年