Я новичок в F #, так что простите меня заранее, если это глупый вопрос или синтаксис может быть немного неправильным. Надеюсь, что в любом случае можно понять суть вопроса.
Чего я хотел бы добиться, так это возможности составить, например, Result
(или Either
или что-то подобное) с различными типами ошибок (дискриминационные союзы) без создания явного дискриминационного союза, который включает в себя объединение двух других дискриминационных объединений.
Позвольте мне привести пример.
Допустим, у меня есть тип Person
, определенный следующим образом:
type Person =
{ Name: string
Email: string }
Представьте, что у вас есть функция, которая проверяет имя:
type NameValidationError =
| NameTooLong
| NameTooShort
let validateName person : Result<Person, NameValidationError>
и другая который проверяет адрес электронной почты:
type EmailValidationError =
| EmailTooLong
| EmailTooShort
let validateEmail person : Result<Person, EmailValidationError>
Теперь я хочу составить validateName
и validateEmail
, но проблема в том, что тип ошибки в Result
имеет разные типы. Чего я хотел бы добиться, так это функции (или оператора), которая позволяет мне делать что-то вроде этого:
let validatedPerson = person |> validateName |>>> validateEmail
(|>>>
- это "волхв c operator")
При использовании |>>>
тип ошибки validatedPerson
будет представлять собой объединение NameValidationError
и EmailValidationError
:
Result<Person, NameValidationError | EmailValidationError>
Просто чтобы прояснить, можно использовать произвольно количество функций в цепочке композиции, например:
let validatedPerson : Result<Person, NameValidationError | EmailValidationError | XValidationError | YValidationError> =
person |> validateName |>>> validateEmail |>>> validateX |>>> validateY
В таких языках, как ReasonML , вы можете использовать что-то под названием polymorphi c варианты , но это недоступно в F # как afaict.
Можно ли как-нибудь имитировать c polymorphi c вариантов, используя обобщения с типами объединения (или любым другим способом) ?! Или это невозможно?