分配具有选项的记录项会引发编译错误

时间:2016-01-20 01:14:56

标签: f#

我对后缀分配的错误感到困惑:

{ First=String20 first; Last=String20 last; Suffix=Some(String20 suffix) }

错误:

  

此表达式应具有类型字符串

代码:

type String20 = String20 of string

type Name = { First:String20
              Last:String20
              Suffix:String20 option }

let tryCreateName (first:string) (last:string) (suffix:string option) = 

    let isValid = [first; last] |> List.forall (fun x -> x.Length > 2 && x.Length <= 20)

    if isValid then 
        Some{ First=String20 first; Last=String20 last; Suffix=Some(String20 suffix) }
    else None

为什么编译器会抱怨?

2 个答案:

答案 0 :(得分:3)

您的函数的suffix参数的类型为string option,所以当你写:

Some(String20 suffix)

您实际上是在string option内包裹String20。你可能需要这样的东西:

suffix |> Option.map String20

这将内部的字符串包装在String20构造函数中的选项中,因此您将得到String20 option

这不验证后缀是否有效(有2到20个字符),但这是另一个问题。

答案 1 :(得分:2)

这将有效

if isValid then 
    let first20 = String20(first)
    let last20 = String20(last)
    let suffix20 =
        match suffix with
        | Some(str) -> Some(String20(str))
        | _ -> None
    let (name : Name) = { First= first20; Last= last20; Suffix= suffix20 }
    Some(name)
else None

但您设计输入的方式要求如下:

printfn "%A" (tryCreateName "John" "Smith" (Some("II")))
printfn "%A" (tryCreateName "Jill" "Smith" None)

这不像Tomas的答案那么优雅,但应该给你更多细节来咀嚼。