我可以像这样从Int
到[Bool]
创建一个简单的地图
import Data.Map (Map)
import qualified Data.Map as Map
simpleMap :: Map Int [Bool]
simpleMap =
Map.insert 1 [True, False] .
Map.insert 1 [False, True] $ Map.empty
编译器告诉我此映射的类型为
simpleMap :: Map Int [Bool]
这一切都很好。
现在,如果我写类似
的内容,我想创建一个从Just a
到[a]
的通用地图。
genericMap :: Map (Maybe a) [a]
genericMap =
Map.insert (Just True) [True, False] .
Map.insert (Just False) [False, True] $ Map.empty
我收到以下编译错误
* Couldn't match type `a' with `Bool' `a' is a rigid type variable bound by the type signature for: genericMap :: forall a. Map (Maybe a) [a] at test.hs:23:1-31 Expected type: Map (Maybe a) [a] Actual type: Map (Maybe Bool) [Bool]
但是,这样的编译还是可以的
genericMap2 :: (Ord a, Num a) => Map (Maybe a) [a]
genericMap2 =
Map.insert (Just 1) [1, 2] .
Map.insert (Just 2) [3, 4] $ Map.empty
我在这里做什么错了?
更新
这只是一个学习练习。理想情况下,我想创建一个HigherMap
数据类型,看起来像这样(用伪代码):
{
Just 1 -> [1, 2, 3],
Just True -> [True, False],
Just "abc" -> ["def", "ghi"]
}
其中的键和值都来自类型构造函数,并且我捕获到两个类型参数相同的信息。
答案 0 :(得分:4)
类似Map (Maybe a) [a]
的类型意味着使用此变量的人将决定要为a
使用哪种类型。这不适用于您的genericMap
定义,因为它试图在其中放置Bool
值,我可能想在其他类型上使用它。
genericMap2
是可以的,因为它使用了多态常数:1 :: (Num a) => a
,因此它可以用于任何(数字)类型,而不像True :: Bool
具有固定类型。