How to return Data.Map from function

This function works:

serialExpansion num = Map.fromList (zip (listOfSimpleDividers num) (powers num)) 

but when I bind:

 serialExpansion :: Int -> Map serialExpansion num = Map.fromList (zip (listOfSimpleDividers num) (powers num)) 

I get an error:

 simplifier.hs:46:26: Not in scope: type constructor or class `Map' 

How to declare a function?

+6
haskell
source share
3 answers

Map is a parameterized data type (also called an abstract data type ). Only when you specify a type for keys and a type for values ​​do you get a fully defined type.

For example, a map that allows you to search for String on Integer is of type Map Integer String .

Also, it looks like you imported the map (as you should). Because of this, you must use Map.Map instead of Map in the signature.

So your function should have a signature like

  serialExpansion :: Int -> Map.Map Key Value 

where Key is the key data type and Value is the data type of the value. In your case, if I were to guess, maybe you want Int for Key and Value . To be precise: you want Key to be the same as the type of the items in the listOfSimpleDividers num list, and Value to be the same as the type of the items in the powers num list. (This can help verify a signature like Map.fromList , if that is unclear).

Now you may ask: "but if you could specify the correct return type serialExpansion , why can't the compiler be?" It can. That is why your first example worked. Since you omitted the type signature, the compiler took it out of context. As you just experienced, writing signature types can be a good way to make sure you fully understand your code (instead of relying on type inference).

+12
source share

Two points to complement the gspr answer:

Common practice is to import a Map type constructor unqualified, and then import the remaining modules:

 import Data.Map (Map) import qualified Data.Map as Map 

This avoids writing Map.Map in all types of signatures.

In addition, in GHCi or Hugs, you can use :t to request an interactive environment for the intended type of any function. For example, if I upload this file to GHCi:

 import Data.Map (Map) import qualified Data.Map as Map serialExpansion num = Map.fromList (zip (listOfSimpleDividers num) (powers num)) where powers = undefined listOfSimpleDividers = undefined 

I get the following:

 *Main> :t serialExpansion serialExpansion :: (Ord k) => t -> Map ka 

If you include your own powers and listOfSimpleDividers , you get a more specific type.

+7
source share

I just wanted to get a card with nothing in it, and then add to it in a more flexible way.

If you want to do something like this, you need Map.empty (assuming you imported it).

0
source share

All Articles