Nik*_*Nik 4 f# pattern-matching
参数类型的模式匹配如何在F#中起作用?
例如,我正在尝试编写简单的程序,如果提供数字则计算平方根,否则返回它的参数.
open System
let my_sqrt x =
match x with
| :? float as f -> sqrt f
| _ -> x
printfn "Enter x"
let x = Console.ReadLine()
printfn "For x = %A result is %A" x (my_sqrt x)
Console.ReadLine()
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
error FS0008: This runtime coercion or type test from type
'a
to
float
involves an indeterminate type based on information prior
to this program point. Runtime type tests are not allowed
on some types. Further type annotations are needed.
Run Code Online (Sandbox Code Playgroud)
由于sqrt与作品float我检查float的类型,但猜测可能有更好的解决办法-像检查,如果输入号码(一般),如果是这样,它转换浮动?
这里的问题x是实际上是一种类型string.添加它来自Console.ReadLine,该字符串中存储的信息类型只能在运行时确定.这意味着您既不能使用模式匹配,也不能使用强制模式匹配.
但是你可以使用Active Patterns.由于存储的实际数据x仅在运行时已知,因此您必须解析字符串并查看包含的内容.
所以假设你期待a float,但你不能确定,因为用户可以输入他们想要的任何东西.我们将尝试解析我们的字符串:
let my_sqrt x =
let success, v = System.Single.TryParse x // the float in F# is represented by System.Single in .NET
if success then sqrt v
else x
Run Code Online (Sandbox Code Playgroud)
但这不会编译:
该表达式应该具有float32类型,但这里有类型字符串
问题是编译器float32根据表达式推断函数返回a sqrt (System.Single.Parse(x)).但是如果x不解析浮动,我们打算只返回它,因为这x是一个字符串,我们在这里有一个不一致.
要解决这个问题,我们必须将结果转换sqrt为字符串:
let my_sqrt x =
let success, v = System.Single.TryParse x
if success then (sqrt v).ToString()
else x
Run Code Online (Sandbox Code Playgroud)
好的,这应该可行,但它不使用模式匹配.所以让我们定义我们的"活动"模式,因为我们不能在这里使用常规模式匹配:
let (|Float|_|) input =
match System.Single.TryParse input with
| true, v -> Some v
| _ -> None
Run Code Online (Sandbox Code Playgroud)
基本上,只有在input可以正确解析为浮点文字的情况下,此模式才会匹配.以下是它在初始函数实现中的使用方法:
let my_sqrt' x =
match x with
| Float f -> (sqrt f).ToString()
| _ -> x
Run Code Online (Sandbox Code Playgroud)
这看起来很像你的功能,但请注意我仍然需要添加.ToString()一下.
希望这可以帮助.
| 归档时间: |
|
| 查看次数: |
1657 次 |
| 最近记录: |