Ambiguous occurrence `take` - haskell

Ambiguous occurrence `take'
It could refer to
either `Prelude.take',
imported from `Prelude' at src\Main.hs:1:8-11
(and originally defined in `GHC.List')
or `Data.Set.take',
imported from `Data.Set' at src\Main.hs:4:1-15
(and originally defined in `Data.Set.Internal')
or `Data.Map.take',
imported from `Data.Map' at src\Main.hs:3:1-15
(and originally defined in `Data.Map.Internal')
|
36 | createMines g fst = Data.Set.fromList $ take mineCount $ shuffle g $
Please tell me how to fix this error.I use import Data.Map and import Data.Set

The reason you get this error is because you imported modules that export functions with the same name. If you then use such function (like take), the compiler does not know what function you aim to use.
You can make a qualified import [Haskell-wiki], so:
import qualified Data.Set as S
You can then use a function the Data.Set module with S.take for example. If you use take, it will use the one defined in the prelude.

Related

How to get a String from a Lazy.Builder?

I need to manipulate the binary encoding as '0' and '1' of simple strings given as input, using ascii 7-bits.
For the encoding I have used the function Data.ByteString.Lazy.Builder.string7 :: String -> Builder
However, I have not found a way to convert back the resulting Builder object into a string of '0' and '1'. Is it possible ? Is there another way ?
Subsidiary question: And if I wanted it in hexadecimal form as text ?
There's an unpackChars function in Data.ByteString.Lazy.Internal. There's also a non-lazy counterpart in Data.ByteString.Internal.
import qualified Data.ByteString.Lazy.Builder as Build
import qualified Data.ByteString.Lazy as BS
import qualified Data.ByteString.Lazy.Internal as BSI
--> BSI.unpackChars $ Build.toLazyByteString $ Build.string7 "010101"
--"010101"
You can also use map (chr . fromIntegral) . BS.unpack instead of unpackChars, but unpackChars is probably faster.
Alternatively, as Michael Snoyman commented below, you could use Data.ByteString.Char8 or its lazy version and you'll get the right conversions to begin with.

Numeric.Probability.Monad not exported from probability package and therefore examples don't work?

I was playing around with the probability package, trying to understand how the various examples work. A number of the examples import Numeric.Probability.Monad which is hidden it seems and therefore means I can't run the examples.
Monty Hall Example:
module Numeric.Probability.Example.MontyHall where
import qualified Numeric.Probability.Distribution as Dist
import qualified Numeric.Probability.Transition as Trans
import Numeric.Probability.Simulation ((~.), )
import Numeric.Probability.Percentage
(Dist, RDist, Trans, )
import qualified Numeric.Probability.Monad as MonadExt
And If i try to run it in ghci
:load "MontyHall.hs"
MontyHall.hs:10:18:
Could not find module `Numeric.Probability.Monad'
it is a hidden module in the package `probability-0.2.4'
Use -v to see a list of the files searched for.
Failed, modules loaded: none.
Clearly I am doing something wrong, as what is the point of examples that can't be run. So what I am doing wrong here?
The only function from Numeric.Probability.Monad used in the MontyHall file is this one:
compose :: Monad m => [a -> m a] -> a -> m a
compose = foldl (flip (<=<)) return
It's a straightforward helper function, and you can just inline it yourself.

How to import an exclamation point (or other operator) from Haskell module

Haskell has a Data.Map module which includes, among other functions, a ! function.
fromList [(5,'a'), (3,'b')] ! 1 Error: element not in the map
fromList [(5,'a'), (3,'b')] ! 5 == 'a'
While I can import other functions from the Data.Map module into my code...
import Data.Map(Map, keys, fromList)
...the following does NOT work...
import Data.Map(Map, keys, fromList, !)
I get the following error:
parse error on input `!'
What is the correct syntax to import items like !?
The correct answer is to wrap the function name (really, it's an operator: a special case of a function) in parentheses, like so...
import Data.Map(Map, keys, fromList, (!))

How do I use Unboxed Vectors?

I am trying to implement a ray data type using the Vector type found here: http://www.haskell.org/haskellwiki/Numeric_Haskell:_A_Vector_Tutorial#Importing_the_library
The Vector will only hold doubles, so I would like to use the Unboxed version of the Vector type.
Here is the code I am trying to compile:
module Main where
import qualified Data.Vector.Unboxed as Vector
data Ray = Ray Data.Vector.Unboxed Data.Vector.Unboxed
The error I get is
Not in scope: type constructor or class `Data.Vector.Unboxed'
Failed, modules loaded: none.
The module Data.Vector.Unboxed exports a type constructor Vector which takes as an argument the type you want to store. Since you renamed this module to Vector as well, the qualified name for this type is Vector.Vector. Assuming you want two vectors of doubles, you should therefore use it like this:
data Ray = Ray (Vector.Vector Double) (Vector.Vector Double)
Normally, when you import something, you do it like this:
import Data.Foo -- A module that contains "data Bar = Bar ..."
myfunction = Bar 3 2 4 -- Use Bar
As you can see, you can access all of the stuff in the Data.Foo module directly, as if you were writing code in that same module.
You can instead import something with qualification, which means that you must specify the full module "path" to the thing that you are referring to every time you access it:
import qualified Data.Foo -- A module that contains "data Bar = Bar ..."
myfunction = Data.Foo.Bar 3 2 4 -- Use Bar
Here, you must specify the full "path" to the data type that you're accessing, because the module has been imported as qualified.
There is another way to import something with qualification; you can specify an alias for the module "path" like so:
import qualified Data.Foo as Foo -- A module that contains "data Bar = Bar ..."
myfunction = Foo.Bar 3 2 4 -- Use Bar
We have renamed the Data.Foo part to simply Foo. This way, we can write Foo.Bar when referring to the data constructor.
You imported the module Data.Vector.Unboxed with the alias Vector. This means that when you want to access the Vector data type, you must use Vector.Vector. I'd recommend that you import vectors like this instead:
import Data.Vector.Unboxed (Vector)
import qualified Data.Vector.Unboxed as Vector
This way, you import the Vector type directly, so that you can access it without any module qualifiers, but when you want to use Vector functions, you need to add the Vector prefix (For example Vector.null ...).

Re-export qualified?

suppose you have two modules like
module Foo.A where
foo = 42
and
module Foo.B where
foo = 12
and you want to write a super module
module Foo (
module Foo.A
, module Foo.B
) where
import Foo.A
import Foo.B
which re-exports those modules, you would get a name clash.
Is there a solution for this?
Basically, no. This has been a long-standing feature request by people like the authors of Gtk2hs. Gtk2hs has a very broad module hierarchy where it might make sense to both:
Use the same name in several different modules (e.g. newButton in both Graphics.UI.Gtk.Buttons.Button and Graphics.UI.Gtk.Buttons.CheckButton)
Provide the convenience to the user of importing all these modules with a single import statement
For now, if you want to reexport several modules together all you can do is:
Avoid reusing names in the modules you wish to reexport
Where appropriate, use type classes to allow the same name to be used for several different purposes
Good question. The Haskell Report addresses this:
Exports lists are cumulative: the set of entities exported by an export list is the union of the entities exported by the individual items of the list.
[...]
The unqualified names of the entities exported by a module must all be distinct (within their respective namespace).
According to my limited Haskell knowledge I'd say it's not possible.
You can't export both foos without the name clash unless you use a typeclass (which I shall elaborate on), but there are other options.
You could opt to hide one of the versions of foo:
module Foo
(
module Foo.A,
module Foo.B
)
where
import Foo.A
import Foo.B hiding (foo)
This isn't ideal if you genuinely need both, but if one is rarerly used then it may be simpler to just hide it and expect people to manually reinclude (e.g. by import qualified Foo.B as B (foo), providing B.foo) it if they need it.
You could opt to hide both versions of foo and document that you expect the end user to manually import them if they need them. Under such a scheme, the user could do something like the following:
import Foo.A as A (foo)
import Foo.B as B (foo)
main :: IO ()
main = do
print A.foo
print B.foo
This is actually a fairly common thing to have to do when dealing with multiple container types since many different container types export functions like empty, null and singleton. (To the point where I wish there were actually typeclasses for those, since they are such common operations.)
If you really need both and you're prepared to do a bit of export gymnasics, you can reexport both under different names from within Foo itself:
module Foo (module Foo) where
-- Note that in this case it is important
-- that the module alias matches the
-- name of the exporting module ('Foo')
import Foo.A as Foo hiding (foo)
import Foo.B as Foo hiding (foo)
import qualified Foo.A
import qualified Foo.B
fooA = Foo.A.foo
fooB = Foo.B.foo
Thus any module importing Foo will get Foo.A.foo as fooA (with a value of 42) and Foo.B.foo as fooB (with a value of 12).
If you only have a few clashes to resolve then this is probably the most balanced solution
As another answer has already mentioned, you can use a typeclass, though depending on the context this may be a misuse of the typeclass system.
You could achieve that like so:
module Foo.C where
-- The 'a' dummy argument is necessary to disambiguate
-- which version of 'foo' you intend to use.
class FooProvider a where
foo :: a -> Int
module Foo.B where
import Foo.C
data FooB = FooB
instance FooProvider FooB where
foo _ = 12
module Foo.A where
import Foo.C
data FooA = FooA
instance FooProvider FooA where
foo _ = 42
module Foo (module Exports) where
-- In this case the name of the
-- module alias is unimportant
-- as long as all modules use the same alias.
import Foo.A as Exports
import Foo.B as Exports
import Foo.C as Exports
import Foo
-- 'FooA' and 'FooB' exist solely for
-- the purpose of disambiguating the
-- different versions of 'foo'.
main :: IO ()
main = do
print (foo FooA)
print (foo FooB)
Generally this is less desirable than the aforementioned solutions, particularly for something as simple as a named constant, but sometimes it makes sense to introduce a typeclass. For example, a typeclass such as this:
class Container c where
empty :: c a
singleton :: a -> c a
null :: c a -> Bool
Would work for a number of container types, including [] ('List'), Set, Maybe. Without singleton, it would apply to even more types (e.g. Map, Seq, IntMap). (Note that this could also have included some kind of length function since an empty container would have a length of 0 and a singleton container would have a length of 1. It would however clash with the length in Prelude, which is based on Foldable.)
There may be other possibilities that make use of typeclasses and possibly compiler extensions, but I suspect they'll only increase in complexity from herein.

Resources