Mac*_*iak 5 f# functional-programming
在我的F#应用程序中,我经常需要对字符串中的字符串执行不区分大小写的搜索,因此我使用适当的比较创建了一个函数:
let indexOf (str:string) (value:string) startIndex =
match str.IndexOf(value, startIndex, StringComparison.OrdinalIgnoreCase) with
| index when index >= 0 -> Some index
| _ -> None
Run Code Online (Sandbox Code Playgroud)
我不喜欢这样的事实,当我想从头开始搜索时,我必须将冗余0作为起始索引.
我对F#和函数式编程都比较陌生,所以我想从功能的角度来看,什么是首选的(最干净的)解决方案?
创建两个版本:
let indexOfFrom (str:string) (value:string) startIndex = (...)
let indexOf str value = indexOfFrom str value 0
Run Code Online (Sandbox Code Playgroud)使用选项类型:
let foundIndex = indexOf "bar foobar" "bar" (Some 4)
Run Code Online (Sandbox Code Playgroud)创建一个专门的歧视联盟:
type Position =
| Beginning
| StartIndex of index : int
let foundIndex = indexOf "bar foobar" "bar" (Index 4)
Run Code Online (Sandbox Code Playgroud)将'indexOf'函数放在一个类型中并使用'经典'重载.
将'indexOf'函数放在一个类型中并使用F#可选参数.
如果将功能定义为F#函数,那么我认为使用两个单独的函数(具有合理的描述性名称)可能是最好的选择。因此,我会选择您的第一个选项(我绝对更喜欢此选项,而不是仅出于此单个目的而定义歧视联盟):
let indexOfFrom (str:string) (value:string) startIndex = (...)
let indexOf str value = indexOfFrom str value 0
Run Code Online (Sandbox Code Playgroud)
另一种方法是将功能定义为类型的成员-然后可以使用重载和F#可选参数,但是必须使用全名来访问它们String.IndexOf
。您可以这样写:
type String =
static member IndexOf(str:string, value:string, startIndex) = (...)
static member IndexOf(str, value) = String.IndexOf(str, value, 0)
Run Code Online (Sandbox Code Playgroud)
或者,使用可选参数:
type String =
static member IndexOf(str:string, value:string, ?startIndex) = (...)
Run Code Online (Sandbox Code Playgroud)
哪个选项是最好的?
如果您正在设计功能性API(例如,特定领域的语言),那么带有两个独立功能的选项可能是最佳选择。
如果您打算设计一个不错的F#API,那么我认为您的选项(多个函数)或可选参数是相当合理的。函数在Deedle中使用率很高,F#图表依赖于可选参数。
使用重载的好处是该库也可以从C#中很好地使用。因此,如果您想从C#调用库,这几乎是唯一的选择。
我认为选项1(带有curried函数)最简单.Curried函数在函数式编程中非常常见.
在选项2或3中,您仍然必须从头开始将附加参数传递给搜索功能
选项4或5需要额外的开销来创建类型.对于这个简单的任务来说,这有点过分了
归档时间: |
|
查看次数: |
1004 次 |
最近记录: |