Помимо аспектов эффективности, есть также прагматическая сторона этого вопроса: что вы хотите сделать с этой структурой?
Вы хотите, например, иметь возможность хранить пустую карту для заданного значения типа a
? Если это так, то необоснованная версия может быть более практичной!
Вот простой пример: предположим, что мы хотим хранить String
-значные свойства людей - скажем, значение некоторых полей на странице профиля стека объекта пользователя.
type Person = String
type Property = String
uncurriedMap :: Map Person (Map Property String)
uncurriedMap = fromList [
("yatima2975", fromList [("location","Utrecht"),("age","37")]),
("PLL", fromList []) ]
curriedMap :: Map (Person,Property) String
curriedMap = fromList [
(("yatima2975","location"), "Utrecht"),
(("yatima2975","age"), "37") ]
С выделанной версией, нет хорошего способа, чтобы записать тот факт, что пользователь "PLL"
известен системе, но не заполнен какой-либо информации. Пара человек/собственность ("PLL",undefined)
будет вызывать сбои во время выполнения, поскольку Map
является строгим в ключах.
Вы можете изменить тип curriedMap
в Map (Person,Property) (Maybe String)
и хранить Nothing
с в там, и это вполне может быть лучшим решением в этого случае; но там, где существует неизвестное/изменяющееся количество свойств (например, в зависимости от вида Person), которые также будут сталкиваться с трудностями.
Таким образом, я предполагаю, что это также зависит от того, нужна ли вам функция запроса, как это:
data QueryResult = PersonUnknown | PropertyUnknownForPerson | Value String
query :: Person -> Property -> Map (Person, Property) String -> QueryResult
Это трудно писать (если не невозможно) в выделанной версии, но легко в uncurried версии.
Я думаю, что «Карта (a, b) c', скорее всего, будет намного больше (и, возможно, времени). Если есть способ (я не уверен, много не использовали карты), чтобы сбрасывать префиксный диапазон ключей, тогда вы все равно могли бы эффективно использовать что-то вроде карри-приложений с этим представлением. – DarkOtter