#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
.