我在module Util
中有以下内容,我广泛使用而没有任何问题:
(>~) = flip fmap
infix 8 >~
(>>~) :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b)
(>>~) = Control.Monad.forM
infix 8 >>~
(显式类型sig只是因为尽管出现了明显的“它只是内置函数的别名”,GHC无法解决这个问题并强迫我这样做,所以让我们在这里忽略它。)< / em>的
现在,在另一个模块(同一个项目)中我导入了上面的运算符,奇怪的是,以下几行 DO 编译得很好:
listAllFiles rootdirpath reldirs modtimer =
let allfiles = (dirpaths >>~ foreachdir) >~~ concat
(>~~) = flip fmap
infix 8 >~~
...
但是下面的变化(我显然更喜欢)将无法编译:
listAllFiles rootdirpath reldirs modtimer =
let allfiles = (dirpaths >>~ foreachdir) >~ concat
...
考虑到在中完全以与导入的{{em>完全相同的方式的方式定义成功的 >~~
如何在本地声明}}?
那里的逻辑在哪里,谁能分享他们对此的见解?哦,这是错误:
>~
..但显然这个问题不是关于如何处理“无法匹配类型'a'与'b'”错误本身/在一般情况下---请记住,在函数式语言中,我希望相同的定义可以相同地工作,无论是在本地Files.hs:88:21: error:
* Couldn't match type `IO' with `[]'
Expected type: [[[(FilePath, Data.Time.Clock.UTCTime)]]]
Actual type: IO [[(FilePath, Data.Time.Clock.UTCTime)]]
* In the first argument of `(>~)', namely
`(dirpaths >>~ foreachdir)'
In the expression: (dirpaths >>~ foreachdir) >~ concat
In an equation for `allfiles':
allfiles = (dirpaths >>~ foreachdir) >~ concat
还是在导入的模块中定义。在这个具体的例子中,什么可能会扰乱这个一般原则?
这不是一个显示阻止者,我可以跳过花哨的操作let
并继续开展业务。但是我想这里可能还有更深入的东西要学习(或者报道一个不起眼的bug)!