上下文如下:
newtype A = A Integer deriving (Eq)
data PairOfA = PairA A A deriving (Eq)
mkPairOfA :: [A] -> A -> A -> Maybe PairOfA
mkPairOfA as a1 a2 =
if a1 `elem` as && a2 `elem` as
then Just (PairA a1 a2)
else Nothing
as1 = [A 1, A 2, A 3]
as2 = [A 1, A 2, A 4]
pair1 = mkPairOfA as1 (A 1) (A 2)
pair2 = mkPairOfA as2 (A 1) (A 2)
main :: IO ()
main = do print $ pair1 == pair2
这是终端中的输出:
ghci> main
True
问题:有没有办法通过它们与不同列表“相关”的事实来以某种方式区分
pair1
和pair2
?我可以定义 PairA 构造函数来假设三个参数而不是两个,即使用列表参数。但是,我不希望我的库的潜在用户必须在每对中存储可能很长的列表,特别是如果他们将使用许多“对”。
在命令式范式中,例如,在一些 OOP 语言(如 Java 或 C++)中,我会使用引用或指针,并将其放入每一对中,无需再三考虑。 Haskell 中的替代方案是什么?如果我要选一个,我会着迷于在字体层面上捕捉它。但如果不可能,我将不胜感激任何其他传统的解决方法。
将列表放入对中。别担心,就像在 Java 或 C++ 中一样,这只是存储对真实事物的引用,因此它同样便宜(或者同样昂贵,如果您愿意)。
data PairWithSourceList = PWSL A A [A] deriving (Eq)
当然,
Eq
实例仍然必须比较完整列表是否相等。但确实没有什么好方法可以避免这种情况。