Набор данных Haskell / тип данных - PullRequest
2 голосов
/ 14 сентября 2011

То, что я хочу сделать, - это создать набор типов в Haskell для представления универсального (полиморфного) набора ex. {1,'x',"aasdf",Phi}

сначала я хочу пояснить, что в моей программе я хочу рассматривать Phi (пустой набор) как нечто, принадлежащее всем наборам

вот мой код

data Set a b= Phi | Cons a (Set a b)
deriving (Show,Eq,Ord)


isMember Phi _ = True
isMember _ Phi = False
isMember x (Cons a b) = if x==a
               then True
               else isMember x b

Я столкнулся с парой проблем:

  1. Я хочу, чтобы isMember type был

    isMember :: Eq a => a -> Set a b -> Bool
    

    но по моему коду это

    isMember :: Eq a => Set a b -> Set (Set a b) c -> Bool
    
  2. Если у меня есть набор разного времени, оператор == не работает правильно, поэтому мне нужна помощь, пожалуйста: D

Ответы [ 3 ]

6 голосов
/ 14 сентября 2011

Что касается вашей ошибки типа, проблема выглядит как первое предложение для меня:

isMember Phi _ = True

Это странное предложение для записи, потому что Phi - это целый набор, а не элемент набора.Простое удаление должно дать вам функцию ожидаемого вами типа.

Обратите внимание, что ваш тип Set никогда не использует свой аргумент второго типа, поэтому он может быть записан вместо этого как

data Set a = Phi | Cons a (Set a)

... и в этот момент вы должны просто использовать [a], поскольку он изоморфен и имеет огромный набор функций, уже написанных для использования и злоупотребления ими.

Наконец, вы просите иметь возможность поставитьвещи разных типов. Короткий ответ: Хаскелл на самом деле так не колеблется.Все дело в том, чтобы точно знать, что это за тип во время компиляции , что на самом деле не совместимо с тем, что вы предлагаете.На самом деле есть несколько способов сделать это;тем не менее, я настоятельно рекомендую познакомиться с особой маркой бондажа Хаскелла, прежде чем пытаться снять облигации.

5 голосов
/ 14 сентября 2011

А) Делать это почти всегда не то, что вы на самом деле хотите.

B) Существует множество способов сделать это от встраивания динамических типов (Dynamic) до использования очень сложных типов (HList).

C) Вот страница с описанием некоторых способов и проблем: http://www.haskell.org/haskellwiki/Heterogenous_collections

D) Если вы действительно собираетесь это сделать, я бы предложил HList: http://homepages.cwi.nl/~ralf/HList/

E) Но если вы начнете просматривать документацию / лист HList и обнаружите, что безнадежно запутались, вернитесь к динамическому решению (или еще лучше, переосмыслите, зачем вам это нужно) и вернитесь к HLists, как только вы значительно удобнее с Haskell.

(О, да, и экзистенциальное решение, описанное на этой странице, вероятно, ужасная идея, поскольку оно почти никогда не приносит вам ничего особенно полезного).

2 голосов
/ 14 сентября 2011

То, что вы пытаетесь сделать, очень сложно, так как Haskell по умолчанию не сохраняет никакой информации о типах.Для этих целей очень полезны два модуля: Data.Typeable и Data.Dynamic.Они предоставляют поддержку для хранения мономорфного (!) Типа и поддерживают динамическую мономорфную печать.

Я не пытался кодировать что-то подобное ранее, но у меня естьнекоторые идеи для этого:

  1. Каждый элемент вашего набора представляет собой тройку (четверку) из следующих вещей:

    • A TypeRep сохраненного типа данных
    • Само значение, приведенное к Any.
    • Функция сравнения (Вы можете использовать только мономорфные значения, выкак-то нужно хранить контекст)
    • similary, функция для show значений.
  2. Ваш набор на самом деле имеет два измерения, сначала деревоTypeRep и затем список значений.

  3. Всякий раз, когда вы вставляете значение, вы вводите его в Any и сохраняете вместе с ним все необходимые данные, как описано в(1) и установите его в правильное положение, как в (2).

  4. Когда вы хотите найтиэлемент, вы генерируете его TypeRep и находите поддерево нужного типа.Затем вы просто сравниваете каждый подэлемент со значением, которое хотите найти.

Это всего лишь некоторые случайные мысли.Я думаю, что на самом деле гораздо проще использовать Dynamic.

...