开发者

How to return Data.Map from function

开发者 https://www.devze.com 2023-01-28 20:41 出处:网络
This function works: serialExpansion num = Map.fromList (zip (listOfSimpleDividers num) (powers num)) but when i tying:

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 Strings by Integers 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).

0

精彩评论

暂无评论...
验证码 换一张
取 消