我正在尝试在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函数(Foldable
和Category
的示例)。
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/