Возврат различного состояния Дискриминационного объединения на основе ввода строки в сопоставлении с образцом (F #) - PullRequest
1 голос
/ 19 марта 2019
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 Ответ

1 голос
/ 20 марта 2019

Как упоминали Рмунн и Романов, ваши 3 функции имеют разные типы.Вы можете заставить их возвращать один тип, например obj -> ColType, используя box & 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
...