gpt4 book ai didi

f# - F# 中的 Haskell 样式到中缀运算符

转载 作者:行者123 更新时间:2023-12-04 16:27:43 25 4
gpt4 key购买 nike

有一个常见的问题是 F# does not natively support Haskell 中可用函数的中缀样式使用:

isInfixOf :: Eq a => [a] -> [a] -> Bool
isInfixOf "bar" "foobarbaz"
"bar" `isInfixOf` "foobarbaz"

可以找到最著名的 F# 解决方案 here :
let isInfixOf (what:string) (where:string) =
where.IndexOf(what, StringComparison.OrdinalIgnoreCase) >= 0
let found = "bar" |>isInfixOf<| "foobarbaz"

此外,使用 native 运算符优先级可以轻松对其进行一些改进:
let ($) = (|>)
let (&) = (<|)
let found = "bar" $isInfixOf& "foobarbaz"

还有 XML-ish </style/> , 描述 here .

我想找到一个更好的解决方案,标准如下:
  • 不破坏常用运算符的单字符运算符(或一对);
  • 它应该是相同的字符,同样在 Haskell 中使用重音(反引号)字符;
  • 它不应该破坏关联性(支持链接):
    let found = "barZZZ" |>truncateAt<| 3 |>isInfixOf<| "foobarbaz"
  • 或者,它应该支持采用元组的函数:
    let isInfixOf (what:string, where:string) = ...
    // it will not work with |> and <|
  • 或者,它应该优雅地处理函数/3:
    val f: 'a -> 'b -> 'c -> 'd = ...
    let curried = a |>f<| b c
    // this wouldn't compile as the compiler would attempt to apply b(c) first

  • 附言各种编码技巧也是受欢迎的,因为我相信好的(由 F# 开发团队检查时)可以在 future 成为语言的一部分。

    最佳答案

    我同意在 Haskell 中将函数转换为中缀运算符的能力在某些情况下是整洁的。但是,我不确定此功能是否适合通常的 F# 编程风格,因为使用成员也可以实现相同的效果。

    例如,让我们以使用 truncateAt 的代码片段为例。和 isInfixOf :

    let found = "barZZZ" |>truncateAt<| 3 |>isInfixOf<| "foobarbaz" 

    如果我们定义 TruncateAtIsInfixOf作为 string 的扩展方法,那么你可以写:
    let found = "barrZZZ".TruncateAt(3).IsInfixOf("foobarbaz") 

    这个版本更短,我个人认为它也更具可读性(特别是对于具有 .NET 编程背景而不是 Haskell 背景的人)。当您点击 . 时,您也会获得智能感知。 ,这是一个不错的奖励。当然,您必须将这些操作定义为扩展方法,因此您需要更加仔细地考虑库的设计。

    为了完整起见,扩展方法定义如下:
    type System.String with
    member what.IsInfixOf(where:string) =
    where.IndexOf(what, StringComparison.OrdinalIgnoreCase) >= 0
    member x.TruncateAt(n) =
    x.Substring(0, n)

    关于f# - F# 中的 Haskell 样式到中缀运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12498159/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com