我正在尝试在Haskell中定义一个Foldable实例,而导入有一些问题。

因此,首先尝试:
模块MyList
哪里

import Data.Foldable

data MyList a = MyList [a]

instance Foldable (MyList) where
  foldr f b (MyList as) = foldr f b as

结果(正常但令人讨厌)

歧义出现“文件夹”

因此,我想我必须将其隐藏在Prelude中:
模块MyList
哪里
import Prelude hiding (foldr)
import Data.Foldable

data MyList a = MyList [a]

instance Foldable (MyList) where
  foldr f b (MyList as) = foldr f b as

编译后,我加载到ghci中并尝试一些基本的东西:
*MyList> foldr (:) "" (MyList "hello")
"hello"
*MyList> foldl (flip (:)) "" (MyList "hello")

<interactive>:1:0:
    Ambiguous occurrence `foldl'
    It could refer to either `Prelude.foldl', imported from Prelude at MyList.hs:4:0-28
                          or `Data.Foldable.foldl', imported from Data.Foldable at MyList.hs:5:0-19
*MyList>

因此,foldr可以工作,而foldl则不行。我的第一个问题是
我是否必须手动隐藏Data.Foldable中从Prelude中定义的每个方法,这是它们实现此目的的一种好方法?

为避免此问题,我尝试进行合格的导入:
模块MyList
哪里
import qualified  Data.Foldable as F

data MyList a = MyList [a]

instance F.Foldable (MyList) where
  foldr f b (MyList as) = foldr f b as

似乎可以在ghc中编译,但是
*MyList> foldr (:) "" (MyList "hello")

<interactive>:1:14:
    Couldn't match expected type `[Char]'
           against inferred type `MyList Char'
    In the third argument of `foldr', namely `(MyList "hello")'
    In the expression: foldr (:) "" (MyList "hello")
    In the definition of `it': it = foldr (:) "" (MyList "hello")

找不到foldr,但令人惊讶的是F.foldr在ghci中工作。
*MyList> F.foldr (:) "" (MyList "hello")
"hello"

但是仅在ghci中,如果我尝试在文件中导入MyList,则foldr,F.foldr,MyList.F.foldr和MyList.foldr无效。

为什么它在ghci中起作用但在实际中不起作用?

我想我必须再次导入Data.Foldable(并再次使用MyList在每个文件中)

有没有更好的方法(例如在MyList中导出Data.Foldable)?

(我是Haskell的新手,尤其是模块的新手)

经过几次回应,似乎没有针对此问题的明确解决方案。但是,我很确定我不是第一个这样做的人,所以

解决此类问题的常用方法是什么?

感谢您的帮助。

最佳答案

这是Thomas Eding解决方案的一种变体,键入的次数更少。基本上,您可以导入(在Prelude中)Prelude隐藏一些函数,然后重新导出Prelude;这将导出减去这些功能的Prelude。通常,此技术对于编写仅重新导出库中某些功能的前端模块很有用。

然后,您也可以重新导出Data.Foldable

我在其中用等效项替换了一些Prelude函数(FoldableCategory的示例)。

module Prelude2 (module Prelude, module Data.Foldable, module Control.Category) where

import Prelude hiding (id, (.), foldr)
import Data.Foldable (Foldable, foldr) -- You might want to import everything.
import Control.Category (Category((.), id))
-- Try out replacing with:
-- import Control.Category ()
-- to see that no (.) is available.

用法:
module Foo where
import Prelude()
import Prelude2

为方便起见,请注意foldr中的(.)Foo的类型,如GHCi所示:
$ ghci Foo.hs
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 2] Compiling Prelude2         ( src-lib/Prelude2.hs, interpreted )
[2 of 2] Compiling Foo              ( /Users/pgiarrusso/AeroFS/Repos/pts-bluevelvet/src-lib/Foo.hs, interpreted )
Ok, modules loaded: Foo, Prelude2.
*Foo> :t foldr
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
*Foo> :t (.)
(.) :: Category cat => cat b c -> cat a b -> cat a c
*Foo>

如果您尝试更换的建议
 import Control.Category ()

GHCi将向您显示(.)中根本没有定义Foo:
*Foo> :r
[1 of 2] Compiling Prelude2         ( src-lib/Prelude2.hs, interpreted )
[2 of 2] Compiling Foo              ( /Users/pgiarrusso/AeroFS/Repos/pts-bluevelvet/src-lib/Foo.hs, interpreted ) [Prelude2 changed]
Ok, modules loaded: Foo, Prelude2.
*Foo> :t (.)

<interactive>:1:1: Not in scope: `.'

关于haskell - 正确导入Haskell的Prelude中已定义的内容的正确方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3175583/

10-09 15:53