Haskell中是否有方法检查一个模块是否导出与另一个模块相同的函数?

Haskell中是否有方法检查一个模块是否导出与另一个模块相同的函数?,haskell,Haskell,我有一些规范(用HSpec编写),希望进行一次测试,检查某些功能的重新导出是否按预期进行 代码: 如果我进入这个文件,如果我手动切换是否注释掉第4行或第5行,我可以使用导入运行所有测试。是否有一种简单的方法可以自动制定规范,确保两个模块输出相同的功能 我想到的第一件事是导入一个合格的模块,并检查是否相等: (($>) == (ComposeLTR.$>)) `shouldBe` True -- Or more succintly ($>) `shouldBe` (Compos

我有一些规范(用HSpec编写),希望进行一次测试,检查某些功能的重新导出是否按预期进行

代码:

如果我进入这个文件,如果我手动切换是否注释掉第4行或第5行,我可以使用导入运行所有测试。是否有一种简单的方法可以自动制定规范,确保两个模块输出相同的功能

我想到的第一件事是导入一个合格的模块,并检查是否相等:

(($>) == (ComposeLTR.$>)) `shouldBe` True
-- Or more succintly
($>) `shouldBe` (ComposeLTR.$>)
但这是行不通的,因为函数是不可直接比较的,它们不是
Eq
type类的一部分

我能想到的唯一一件自动工作的事情是导入合格的并为所有4个函数定义QuickCheck属性,如下所示:

import qualified ComposeLTR

it "should re-export the same function" $ do
  let
    prop :: (Fun Int Int) -> Int -> Bool
    prop (Fun _ f) g = (g $> f) == (g ComposeLTR.$> f)
  property prop

-- ... Essentially repeated 3 more times
但这似乎是非常冗长和多余的。是否有一种优雅的方法来检查此问题?

您可以在IO中使用s:

Prelude Data.List System.Mem.StableName>v'v==v'
真的

即使函数有一个
Eq
实例,它也是一个无用的实例。函数相等是不可判定的,因此无论如何实现,它都会返回错误的结果。不一定。可以检查普通情况下的相等性,这在我的特定情况下很有用:
fn==fn
,或者更简单的是:
let fn'=fn in fn==fn'
。因此,在这些情况下,指向这些函数的指针是相同的,AFAIU,并且可以进行比较。例如,在JavaScript中可以像这样比较函数;如果返回true,则可以确定它们是相同的。如果返回false,它们的行为可能仍然相同,但我们至少知道它们的指针指向不同的内存地址?不,真的,除了完全不符合Haskell的精神之外,用指针相等代替相等也不是很有用:因为值经常被重新包装、重新排列、标识组合等等。。所有这些都将打破指针相等,尽管它保持了结构。-为了检查不同的模块是否导出相同的内容,正确的解决方案肯定会在语法/模块级别上运行,而不是在值级别上运行?此外,指针相等会破坏引用的透明性,使其既无用又非法。它确实是这样做的,因为引用不再透明。这意味着我不能用
foo
替换
id foo
,并生成一个等价的程序。对于“beautiful”的某个定义,这就是beautiful!
Prelude Data.List System.Mem.StableName> v  <- makeStableName   Prelude.takeWhile
Prelude Data.List System.Mem.StableName> v' <- makeStableName Data.List.takeWhile
Prelude Data.List System.Mem.StableName> v == v'
True