2013-02-12 2 views
4

Я пытаюсь создать новое объявление данных, называемое местом.Использование значения по умолчанию в выражении case в Haskell

Это выглядит следующим образом:

data place = United States | France | England | Germany | Mexico | Canada

Моя надежда состоит в том, чтобы затем использовать функцию под названием колпачок, чтобы занять место в его капитал, как так:

cap :: place -> String 
cap a = case a of 

      Spain   -> "Madrid" 
      France   -> "Paris" 
      England   -> "London" 
      Germany   -> "Berlin" 
      Mexico   -> "Mexico City" 
      Canada   -> "Ottawa" 
      _    -> undefined 

Однако последний случай, где я пытаюсь поймать все другие записи, которые могут не существовать в декларации данных, не работает. Если я вхожу в capital Wales, например, в GHCI, я не получаю неопределенный ответ. Вместо этого я получаю ошибку не в области. Может ли кто-нибудь помочь мне с моей путаницей и, возможно, предоставить законный способ попытаться поймать другие случаи?

+0

Временно добавьте другую страну в данные вашего кода. Place = Temp | Соединенные Штаты Америки | ... 'тогда вы можете проверить' cap Temp'. – AndrewC

+2

(Ваше объявление данных нарушено на данный момент. Оно должно указывать «данные Place = UnitedStates | France | England | Germany | Mexico | Canada'.) – AndrewC

ответ

9

Проблема не в том, как вы обрабатываете недостающие случаи - как вы делаете это нормально. Проблема в том, что конструктор Wales просто не существует. Так же, как когда вы пытаетесь использовать переменную или функцию, которая не была определена, вы получаете ошибку компиляции. Ваша функция cap никогда не вызывается, поэтому никакие изменения, которые вы могли бы сделать с ней, не повлияли бы на это поведение. Вы ничего не можете сделать, чтобы сделать код, который использует компиляцию несуществующих конструкторов.

4

Когда вы вводите capital Wales, в сфере видимости нет Wales. Невозможно построить значение, которое не существует. Если вы рассмотрели все возможные случаи, вам не нужен случай по умолчанию.

+0

Это имеет смысл. Невозможно придумать вариант «ловить» по умолчанию, хотя, если пользователь не знал, что только эти страны были в декларации? – ZAX

+0

@ZAX ваш синтаксис верен для случая по умолчанию, но нет способа передать значение, которое вызывает этот случай. Компилятор сначала поймает ошибку :) – singpolyma

3

Чтобы получить ответы на sepp2k и singpolyma, дело здесь в том, что типы объединения Haskell являются исчерпывающим. Когда вы определяете тип объединения с n случаями, вы сообщаете Haskell, что те случаи, которые существуют для вашего типа, являются единственными случаями, которые существуют для вашего типа. Как указывает singpolyma, вы сказали Haskell, что в других случаях нет даже .

У этого есть преимущества и недостатки. Исчерпание означает, что вы и компилятор можете гарантировать, что ваши функции будут обрабатывать все возможные входы, которые им будут предоставлены. Недостатком является то, что множество случаев фиксировано во время компиляции.

Самый простой альтернативой здесь состоит из двух частей:

  1. Используйте «открытый» типа, для которого вы можете создать сколь угодно много разных экземпляров во время выполнения-представлять страны и столицы. Строки здесь хорошие; существует бесконечное количество различных строк, которые вы можете построить во время выполнения. Но вы также можете использовать тип записи со строковым элементом.
  2. Используйте структуры данных с привязкой к значению/значению, чтобы представить связь между странами и столицами.

Таким образом, вы могли бы представлять страны и города, как это:

-- Since there are infinitely many different strings you could construct at runtime, 
-- there are also infinitely many different Cities and Nations... 
data City = City String deriving (Eq, Ord, Show) 
data Nation = Nation String deriving (Eq, Ord, Show 

Самый простой ключ/значение типа отображение [(k, v)], часто известный как список ассоциации. Это, конечно, O (n) время поиска. Лучше всего использовать Data.Map, который поставляется с платформой Haskell.

+2

Или он может добавить термин «Другие строки» в свой союз как резерв. –

Смежные вопросы