Ошибка в реализации Data.Map? - программирование
Подтвердить что ты не робот

Ошибка в реализации Data.Map?

Я наткнулся на что-то, что, как я предполагаю, является ошибкой в ​​ Data.Map, но также вполне возможно, является ошибкой в ​​моих знаниях Haskell. Надеясь, что кто-нибудь сможет уточнить, что это такое:)

Пожалуйста, укажите этот смысл. Я сериализую циклическую связанную структуру списка с потоком. Для любого заданного node вида:

data Node = Node
  { val  :: Word8
  , next :: Node
  }

Я ожидаю, что он будет сериализован как пара байтов: первый байт, представляющий val, а второй байт, представляющий смещение в байтовом потоке, где next может быть расположен. Например, я ожидаю:

let n0 = Node 0 n1
    n1 = Node 1 n0

будет сериализована как [0, 1, 1, 0]. Ничего страшного.

Немного сложная часть здесь заключается в том, что я использую экземпляр MonadFix для RWST для "связывания узла" смещений bytestream: я поддерживаю карту от узлов до смещений, заполняя карту во время сериализации, но также ссылаясь на записи на карте, которые не обязательно существуют до завершения сериализации.

Это отлично работает, когда реализация карты Data.HashMap.Lazy (от unordered-containers). Однако, когда реализация является обычной Data.Map (от containers), переполнение стека программы - никакая каламбур не предназначена - Map пытается бесконечно сравнивать два узла с помощью (==).

Итак, мой вопрос: - это ошибка в Data.Map, или мои предположения о том, как эти структуры должны вести себя в присутствии mfix ошибочных?

4b9b3361

Ответ 1

Ваш экземпляр Ord не работает:

instance Ord Node where -- for use in Data.Map
  Node a _ < Node b _ = a < b

Для рабочего экземпляра Ord вы должны определить compare или (<=). Если вы определяете только (<), любой вызов compare или (<=) будет зацикливаться бесконечно, так как обе имеют реализацию по умолчанию в терминах друг друга. Также остальные члены Ord определены в терминах compare, поэтому ничего, кроме (<), не будет работать.