Совпадение шаблона Haskell - как использовать константу переменных

В идеале я бы хотел написать что-то вроде этого:

myValue1 = 1 :: Int
myValue2 = 2 :: Int

myFunc :: Int -> Bool
myFunc myValue1 = True
myFunc myValue2 = False

Вызов myFunc myValue2 возвращает True - не то, что я намерен. Я знаю, почему это происходит, но есть ли способ выразить это в Haskell, не прибегая к утверждениям #define C-стиля?

Ответы

Ответ 1

Ну, Haskell не объединяет имена вроде этого. Эти новые идентификаторы "myValue1" и "2" являются новыми переменными, которые вы связываете.

Самый способ Хаскели - использовать сильные типы и сопоставление шаблонов:

data Values
   = D1
   | D2

myFunc :: Values -> Bool
myFunc D1 = True
myFunc D2 = False

Предоставляя вам статическую гарантию, для myFunc можно передать только "1" или "2", правильное символическое сопоставление и даже сохранить преобразование в целые числа, выведя Enum.

Ответ 2

Вы не можете сопоставлять значения переменных, как объяснил Дон.

Но вы можете использовать защитные устройства в этом случае:

myValue1 = 1 :: Int
myValue2 = 2 :: Int

myFunc :: Int -> Bool
myFunc x
  | x == myValue1 = True
  | x == myValue2 = False

Ответ 3

Если вы не хотите создавать другой тип данных, обычным решением является использование защитных устройств:

myValue1 = 1 :: Int
myValue2 = 2 :: Int

myFunc :: Int -> Bool
myFunc val | val == myValue1 = True
           | val == myValue2 = False

То, что вы положили после того, как труба может быть любым логическим условием; если оно истинно, будет запущено соответствующее тело функции.

Ответ 4

Если идея состоит в том, чтобы определить некоторые константы для использования в шаблонах, вы также можете использовать расширение языка PatternSynonyms:

{-# LANGUAGE PatternSynonyms #-}

pattern MyValue1 = 1
pattern MyValue2 = 2

myFunc :: Int -> Bool
myFunc MyValue1 = True
myFunc MyValue2 = False