I'm trying to define a Foldable instance in Haskell and I have some problem with import.
So first try : module MyList where
import Data.Foldable
data MyList a = MyList [a]
instance Foldable (MyList) where
foldr f b (MyList as) = foldr f b as
Result (normal but annoying)
Ambiguous occurrence `foldr'
So, I guess I have to hide it from the Prelude : module MyList where
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
This compile, I load into ghci and try some basic stuff :
*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>
So foldr works, but foldl doesn't. My first question is
To avoid this problem , I tried to do an qualified import : module MyList where
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
Seems to compile in ghc but
*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 is not found but suprisingly F.foldr works in ghci.
*MyList> F.foldr (:) "" (MyList "hello")
"hello"
But in ghci only, if I'm trying to import MyList in file, foldr, F.foldr, MyList.F.foldr and MyList.foldr doesn't work.
I guess I have to import Data.Foldable again (and again in every files using MyList)
(I'm a newbie in Haskell and especially with modules)
After having a couple of responses, it seems there is no clean solution to this problem. However, I'm pretty sure I'm not the first doing that, so
Thanks for you help.
The syntax for importing modules in a Haskell script is import <module name>. This must be done before defining any functions, so imports are usually done at the top of the file. One script can, of course, import several modules. Just put each import statement into a separate line.
Prelude is a module that contains a small set of standard definitions and is included automatically into all Haskell modules.
A qualified import allows using functions with the same name imported from several modules, e.g. map from the Prelude and map from Data.
Haskell's module design is relatively conservative: the name-space of modules is completely flat, and modules are in no way "first-class." Module names are alphanumeric and must begin with an uppercase letter. There is no formal connection between a Haskell module and the file system that would (typically) support it.
Why does it work in ghci but not in real?
Because in your GHCi session you were typing expressions in the context of the MyList
module, so F.foldr
was in scope, but if you import MyList
into another module then only the names exported by MyList
, and the other modules you imported, are in scope.
Your guess is correct - in every module using Data.Foldable.foldr
, you have to
import qualified Data.Foldable as F
The names exported by a module are unqualified; the qualification or not of those names is decided when the module is imported.
There have been proposals over the years to allow exporting qualified names, but to date nothing has been implemented.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With