Хаскель тип - PullRequest
       9

Хаскель тип

2 голосов
/ 16 января 2012

Как я могу найти тип значения в Haskell?

Я хочу что-то вроде этого:

data Vegetable = 
  Und Under
 |Abv Above

is_vegetable ::a->Bool  
is_vegetable a = if (a is of type Vegetable) then True else False

Обновление:

Я хочуструктура данных для моделирования вышеприведенного дерева.

Я также хотел бы иметь некоторые функции (is_drink, is_vegetable, is_wine, is_above), чтобы я мог применить некоторые фильтры к списку.enter image description here

Ответы [ 3 ]

15 голосов
/ 16 января 2012

Ты не. Вы полагаетесь на систему типов, чтобы гарантировать, что значением является Vegetable - если значение не является Vegetable, ваша программа не будет компилироваться, тем более запускаться.

is_vegetable :: Vegetable -> Bool
is_vegetable _ = True  -- so there is not much point to this function

Изменить, увидев ваш комментарий:

data Foodstuff = Vegetable Vegetable
               | Drink Drink

is_vegetable :: Foodstuff -> Bool
is_vegetable (Vegetable _) = True
is_vegetable _             = False

Но это, вероятно, все еще не то, что вы хотите. Вместо этого вы, вероятно, хотите что-то вроде

    case myFood of
         Vegetable vegetable -> -- something involving `vegetable`
         Drink drink         -> -- something involving `drink`
9 голосов
/ 16 января 2012

Вы не можете сделать это в Haskell. Все аргументы функции имеют конкретные типы (например, Int и String) или они переменные типа (например, a в вашем примере). Переменные типа могут быть ограничены принадлежностью к определенному классу типов .

Когда вы используете переменную неограниченного типа, вы не можете делать ничего интересного со значениями этого типа. Ограничивая переменную типа классом типа, вы получаете больше возможностей: если у вас есть Num a, то вы знаете, что a является числовым типом, и поэтому вы можете добавить, несколько и т. Д.

Из вашего комментария кажется, что вам нужен (больший) тип данных для хранения различных типов элементов в вашем дереве. Тип Either a b может пригодиться здесь. Это либо Left a, либо Right b, поэтому у вас может быть такая функция, как

is_vegetable :: Either Vegetable Drink -> Bool
is_vegetable (Left _) = True
is_vegetable (Right _) = False

Тогда ваши узлы дерева будут Either Vegetable Dring элементами.

5 голосов
/ 16 января 2012

Подсказка для чтения сигнатур функций в Haskell:

f :: a -> Bool

Это означает, что f принимает один аргумент, который может быть что угодно , а f не имеет никакой информации о типе. Так что f не может знать, является ли аргумент Vegetable. Есть только три возможных определения для f (еще два для строгих / нестрогих вариантов, которые я опущу для ясности):

-- version 1
f _ = True

-- version 2
f _ = False

-- version 3
f _ = undefined

Видите ли, f - очень скучная функция, потому что ей не разрешено ничего знать о ее параметре. Вы могли бы сделать что-то вроде этого:

isVegetable :: Typeable a => a -> Bool
isVegetable x = case cast x :: Maybe Vegetable of
                  Just _ -> True
                  Nothing -> False

Вам необходимо создать экземпляр Typeable для Vegetable,

data Vegetable = ... deriving Typeable

Подпись f :: Typeable a => a -> Bool означает, что f имеет один параметр, и он ничего не знает об этом параметре, за исключением того, что параметр имеет тип, известный во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...