Ваше заявление о IntOrString
типа, кажется, указывает, что вы хотите, тип, который может содержать целое число или строку. Однако это не то, что вы создали. Я рекомендую прочитать section on Union Types в Руководстве по вязанию.
Когда вы объявляете тип объединения, вам нужно создать конструкторы. В вашем примере вы на самом деле создаете тип с двумя конструкторами, ни один из которых не содержит параметра, поэтому, хотя вы называете их Int
и String
, они не имеют отношения к родным Int
и String
города Эльма. В этом случае их можно считать примерно эквивалентными перечислению внутри языка, такого как C# или Java.
Кроме того, ваше объявление вызывает путаницу компилятора, потому что вы создали имена конструкторов, которые сталкиваются с существующими типами, поэтому в другом месте вашего кода компилятор путается, что вы имеете в виду, когда говорите Int
или String
.
Давайте переопределим тип так, чтобы он стал единственным типом, который может содержать целое или строковое значение. Я также переименую конструкторы, чтобы избежать конфликтов имен.
type IntOrString
= MyString String
| MyInt Int
И теперь вы можете настроить функцию getInt
на основе нового определения. Обратите внимание на то, как соответствующий шаблон используется, чтобы вытащить строку или целочисленное значение из значения IntOrString
на основании которого конструктор был использован для его создания:
getInt : IntOrString -> String
getInt intOrString =
case intOrString of
MyString s ->
s
MyInt i ->
toString i
Привет Чад, спасибо за разъяснения. Я думал о типах Союза на таких языках, как машинопись, где вы можете комбинировать с любым встроенным типом. но это что-то другое с тем же именем. – Prabhjot