#types #f# #pattern-matching #discriminated-union
#типы #f# #сопоставление с шаблоном #дискриминируемое объединение
Вопрос:
type ColType = I of int | S of string | F of float
Я знаю, что вы не можете вернуть тип, отличный от сопоставления с шаблоном, поэтому я создал этот тип в первую очередь для синтаксического анализатора, который я создаю. Однако с этим кодом:
//create i coltype
let m (x : int) : ColType =
ColType.I x
//create f coltype
let n (x : float) : ColType =
ColType.F x
//create s coltype
let b (x : string) : ColType =
ColType.S x
let pColType =
let innerFn (charList : char list) =
let i = String(List.toArray charList)
match i with
| "int" -> m
| "float" -> n
| "string" -> b
many1 parseLowercase |>> innerFn
Это все равно выдаст мне ошибку в функции pColType, несмотря на то, что m, n и b возвращают один и тот же тип.
код, такой как parseLowercase и т.д., — это просто код для получения строки, он функционирует как задумано, проблема в том, что возвращаемое значение не является одинаковым, несмотря на то, что все они являются coltype? (несмотря на разные его состояния).
Комментарии:
1. Сейчас у меня нет времени на полный ответ, но тип функции включает все ее входные данные.
m
,n
иb
бывают трех разных типов:int -> ColType
,float -> ColType
иstring -> ColType
. Итак, вашеmatch i with
выражение возвращает три разных типа, а это недопустимо.2. Проблема в том, что все ветви a
match
должны иметь один и тот же тип, и в вашем случае этими ветвями являютсяm : int -> ColType
,n : float -> ColType
иb : string -> ColType
. Они возвращают один и тот же тип, но они должны иметь один и тот же тип.
Ответ №1:
Как упоминали rmunn и Romanov, ваши 3 функции имеют разный тип. Вы можете заставить их возвращать один тип, например, obj -> ColType
используя box
amp; unbox
:
let pColType =
let innerFn (charList : char list) =
let i = String(List.toArray charList)
match i with
| "int" -> unbox >> m
| "float" -> unbox >> n
| "string" -> unbox >> b
|_-> failwithf "error %A" i
many1 parseLowercase |>> innerFn
Для этого требуется, чтобы вы box
ввели значение перед вызовом результирующей функции.
Поскольку вы создаете синтаксический анализатор, имеет смысл вместо этого заставить его возвращать string -> ColType
:
let pColType =
let innerFn (charList : char list) =
let i = String(List.toArray charList)
match i with
| "int" -> parseInt >> m
| "float" -> parseFloat >> n
| "string" -> parseString >> b
|_-> failwithf "error %A" i
many1 parseLowercase |>> innerFn