数据稳定名称 a
稳定名称具有以下属性:如果sn1 :: StableName和sn2 :: StableName和sn1 == sn2,则通过在同一对象上调用makeStableName创建sn1和sn2.
反过来不一定如此:如果两个稳定名称不相等,那么它们命名的对象可能仍然相等.
reallyUnsafePtrEquality# :: a - > a - > Int#
reallyUnsafePtrEquality#返回GHC堆上的两个对象是否是同一个对象.它真的不安全,因为垃圾收集器会移动东西,闭包等.据我所知,它可以返回假阴性(它说两个对象不一样,但它们都是),但不是误报(说它们当他们不是时,他们会一样.
他们两个似乎做了同样的基本事情:他们可以告诉你两个对象是否绝对相同,但不是它们是否绝对不是.
我能看到的StableNames的优点是:
我可以在reallyUnsafePtrEquality#中看到的优点:
我的问题是:
我错过了什么吗?
是否有任何用例,StableNames与他们命名的对象分开是有利的?
是否比另一个更准确(不太可能返回假阴性)?
如果你不需要散列,不关心可移植性,并且不会被使用名为reallyUnsafe的东西所困扰,是否有理由更喜欢StableNames而不是reallyUnsafePtrEquality#?
在Scheme中,原语eq?测试其参数是否是同一个对象.例如,在以下列表中
(define lst
(let (x (list 'a 'b))
(cons x x)))
Run Code Online (Sandbox Code Playgroud)
的结果
(eq? (car x) (cdr x))
Run Code Online (Sandbox Code Playgroud)
是真实的,而且它是真实的,而不具有窥视(car x)和(cdr x).这允许您为具有大量共享的数据结构编写有效的相等性测试.
在Haskell中是否可以做同样的事情?例如,请考虑以下二叉树实现
data Tree a = Tip | Bin a (Tree a) (Tree a)
left (Bin _ l _) = l
right (Bin _ _ r) = r
mkTree n :: Int -> Tree Int
mkTree 0 = Tip
mkTree n = let t = mkTree (n-1) in Bin n t t
Run Code Online (Sandbox Code Playgroud)
在每个级别都有共享.如果我创建一棵树 …
在Haskell中,我们有一个函数(==) :: Eq a => a->a->Bool,它适用于Eq可以定义实例的大量数据类型.但是,有些类型没有合理的方法来定义实例Eq.一个例子是简单的函数类型(a->b)
我正在寻找一个函数,告诉我两个值是否实际相同 - 不相等但相同.
例如f(id,id)==> True f((+),(-))= False
澄清:
我并不想知道如果两个函数做同样的事情.在一般情况下,这是不可能的.我想知道我是否已经回到了与我开始时相同的事情.让我举一个精简的例子:
data Foo = Foo (Foo->Foo) --contains a function so no Eq instance
x :: Foo
x = Foo id -- or for that matter Foo undefined
y :: Foo
y = Foo (const x)
a :: Foo
a = let (Foo fy) = y
in fy x
Run Code Online (Sandbox Code Playgroud)
很明显,通过检查一旦评估,a将是x.但是我们假设我不知道y中的函数但我想测试我放入的Foo是否与我回来的相同 - …
从2014 年开始在邮件列表上的这个条目似乎表明答案是否定的.如果它仍然没有,我怎么能快速比较两个巨大的数据结构,其中一个是另一个的完全匹配,或稍微改变的版本?