Работа с конструкторами значений в Haskell

#haskell #value-constructor

#haskell #значение-конструктор

Вопрос:

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

 dividing (Number 50) (Number 10)
  

А затем выведите что-то вроде:

 Number 10
  

Я попробовал это:

 data Number = Ok Double | Error String deriving Show

dividing :: Number -> Number -> Number
dividing (Number num1) (Number num2) = (Ok (num1/num2))
  

Но я получаю эти ошибки на терминале:

 35.hs:288:10: error: Not in scope: data constructor ‘Number
35.hs:288:24: error: Not in scope: data constructor ‘Number
  

Наиболее приблизительным рабочим кодом, который я получил, был приведенный ниже код, но пользователь должен ввести Ok или Error, чтобы выполнить операцию, что является реальным обходным путем:

 data Number = Ok Double | Error String deriving Show

dividing :: Number -> Number -> Number
dividing (Ok num1) (Ok num2) = (Ok (num1/num2))
dividing (Ok num1) (Error "0") = (Error ("You can't divide by zero"))
  

Я хотел бы знать лучший способ получать числа напрямую, а не получать конструкторы значений.

Комментарии:

1. Сопоставление с шаблоном (Ok 0.0) перед сопоставлением (Ok num2) . Это должно охватывать особый случай. Не сопоставляйте (Error "0") , а в целом (Error e) — подумайте о случае dividing (Ok 23.0) (dividing (Ok 42.0) (Ok 0.0))) и о том, что должно произойти с Error ("You can't divide by zero") тем, что создается во внутреннем приложении.

2. Нет, нет лучшего способа получать числа напрямую вместо получения конструкторов значений. Конструкторами значений являются числа.

3.Если один аргумент является ошибкой, вам просто нужно распространить его как возвращаемое значение. Если оба аргумента являются ошибками, неясно, следует ли вам распространять ту или иную ошибку или вы должны объединить их в новое Error значение.

Ответ №1:

Зачем беспокоиться о Ok и Error ? Вы хотите создать конструктор числовых данных, поэтому просто назовите его Number :

 -- "Number" on the left signifies the number type
-- "Number" on the right signifies the number data constructor
data Number = Number Double deriving (Show)

dividing :: Number -> Number -> Number
-- division by 0 doesn't need to be handled since it's Infinity by the floating point standard
dividing (Number a) (Number b) = Number (a / b)
  

Комментарии:

1. Спасибо! Но это упражнение требует работы с Ok и Error, чтобы возвращать ошибку, когда сопоставление с шаблоном получает 0 во втором аргументе. Но я действительно застрял на этом…

2. @LuanTorres Если Ok и Error требуются, но в тестовом примере используется (Number 50) что-то не так. Либо вы неправильно прочитали свое упражнение, либо тот, кто его написал, допустил ошибку. Если это присваивание, перечитайте его внимательно. Если вы все еще убеждены, что вам нужны Ok Error конструкторы значений и, но тест должен использовать Number 50 , обратитесь к своему инструктору с вопросом, может ли быть опечатка в тестовом примере, и они на самом деле имели в виду Ok 50 .