我对后缀分配的错误感到困惑:
{ 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
为什么编译器会抱怨?
答案 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的答案那么优雅,但应该给你更多细节来咀嚼。