F# 分配具有选项的记录项会引发编译错误
我对后缀分配的错误感到困惑:F# 分配具有选项的记录项会引发编译错误,f#,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:s
{ 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
错误:
{ 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
此表达式应具有字符串类型
代码:
{ 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
类型String20=字符串的String20
类型名称={First:String20
最后:第20条
后缀:String20选项}
让tryCreateName(第一个:字符串)(最后一个:字符串)(后缀:字符串选项)=
让isValid=[first;last]|>List.forall(fun x->x.Length>2&&x.Length函数的后缀
参数的类型为字符串选项
,因此在编写时:
Some(String20 suffix)
实际上,您正在尝试将string选项
包装到String20
中。您可能需要以下内容:
suffix |> Option.map String20
这会将字符串包装在String20
构造函数中的选项内,因此您将得到String20选项
这并不能验证后缀是否有效(有2到20个字符),但这是另一个问题。函数的后缀
参数的类型为字符串选项
,因此在编写时:
Some(String20 suffix)
实际上,您正在尝试将string选项
包装到String20
中。您可能需要以下内容:
suffix |> Option.map String20
这会将字符串包装在String20
构造函数中的选项内,因此您将得到String20选项
这不会验证后缀是否有效(有2到20个字符),但这是另一个问题。这会起作用
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)
这并不像托马斯的回答那么优雅,但应该给你更多的细节来仔细考虑。这会有用的
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的回答那么优雅,但应该给你更多的细节让你仔细思考。作为旁白,你可能想看一下页面的一半。这将要求你使用元组作为输入,而不是咖喱。然后你就可以摆脱对后缀的一些或没有要求。顺便说一句,你的代码有一个微妙的错误。你没有验证后缀长度::)最好将String20构造函数设置为私有,并使用一个特殊的“智能”构造函数进行验证。这样,您就永远不会意外地拥有无效的String20。不过,这完全是另一个话题!作为旁白,你可能想看看这一页的一半。这将要求您对输入使用元组,而不是咖喱。然后,您可以取消对后缀的部分或全部要求。顺便说一句,您的代码有一个微妙的错误。您没有验证后缀长度。:)最好将String20构造函数设置为私有,并使用一个特殊的“智能”构造函数进行验证。这样,您就永远不会意外地拥有无效的String20。不过,这完全是另一个话题!这可能也会使验证逻辑的实现更加容易!这可能也会使验证逻辑的实现更加容易!