How to return Data.Map from function
This function works:
serialExpansion num = Map.fromList (zip (listOfSimpleDividers num) (powers num))
but when i tying:
serialExpan开发者_如何学Gosion :: Int -> Map
serialExpansion num = Map.fromList (zip (listOfSimpleDividers num) (powers num))
i get the error:
simplifier.hs:46:26: Not in scope: type constructor or class `Map'
How must I declare the function?
Map
is a parameterized data type (also called an abstract data type). Only when you specify a type for the keys and a type for the values do you get a fully defined type.
For example, a map that lets you look up String
s by Integer
s has the type Map Integer String
.
Also, it seems you've imported Map qualified (as you should). Because of this, you have to use Map.Map
instead of just Map
in the signature.
Thus, your function should have a signature like
serialExpansion :: Int -> Map.Map Key Value
where Key
is the key data type and Value
is the value data type. In your case, if I were to guess, perhaps you want Int
for both Key
and Value
. To be precise: you want Key
to be the same as the type of the elements in the list listOfSimpleDividers num
, and Value
to be the same as the type of the elements in the list powers num
. (It might help to inspect the type signature of Map.fromList
if this is unclear).
By now you might be asking: "but if you were able to tell the correct return type of serialExpansion
, why can't the compiler?" It can. That's exactly why your first example worked. Since you omitted the type signature, the compiler inferred it from context. As you just experienced, writing type signatures can be a good way to make sure you fully understand your code (instead of relying on type inference).
Two points to supplement gspr's answer:
It's a common practice to import the type constructor Map
unqualified and then import the rest of the module qualified:
import Data.Map (Map)
import qualified Data.Map as Map
This allows you to avoid writing Map.Map
in your type signatures everywhere.
Also, in either GHCi or Hugs you can use :t
to ask the interactive environment for the inferred type of any function. For example, if I load this file in 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 k a
If you plug in your own definitions of powers
and listOfSimpleDividers
you'll get a more specific type.
I was just looking to get a map with nothing in it and then add to it in a more flexible way.
If you want to do something similar you need Map.empty
(assuming you've imported it qualified).
精彩评论