5

Haskell で利用可能な関数の中置式スタイルの使用を F#がネイティブにサポートしていないという一般的な問題があります。

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

F# の最もよく知られているソリューションは、次の場所にあります

let isInfixOf (what:string) (where:string) =
    where.IndexOf(what, StringComparison.OrdinalIgnoreCase) >= 0
let found = "bar" |>isInfixOf<| "foobarbaz"

また、ネイティブの演算子の優先順位を使用して、少し改善するのは簡単です。

let ($) = (|>)
let (&) = (<|)
let found = "bar" $isInfixOf& "foobarbaz"

ここ</style/>で説明されているXML っぽいものもあります。

次の基準で、より良い解決策を見つけたいと思います。

  • 一般的に使用される演算子を破棄しない単一文字演算子 (またはペア)。
  • これは同じ文字でなければなりません。同様に、Haskell ではグレーブ アクセント (バック クォート) 文字が機能します。
  • 結合性を破壊するべきではありません (連鎖をサポートします):

    let found = "barZZZ" |>truncateAt<| 3 |>isInfixOf<| "foobarbaz"
    
  • オプションで、タプルを取る関数をサポートする必要があります。

    let isInfixOf (what:string, where:string) = ...
    // it will not work with |> and <|
    
  • オプションで、functions/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
    

PS さまざまなコーディング トリックも歓迎します。良いもの (F# 開発チームによってチェックされた場合) は、将来的に言語の一部になる可能性があるからです。

4

2 に答える 2

17

Haskell で関数を中置演算子に変換する機能は、状況によっては優れていることに同意します。ただし、この機能が通常の F# プログラミング スタイルにうまく適合するかどうかはわかりません。同じことがメンバーを使用して実現できるからです。

truncateAtたとえば、 andを使用するスニペットを見てみましょうisInfixOf:

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

の拡張メソッドとしてとを定義するTruncateAtと、次のように記述できます。IsInfixOfstring

let found = "barrZZZ".TruncateAt(3).IsInfixOf("foobarbaz") 

このバージョンは短く、個人的にはより読みやすいと思います (特に、Haskell のバックグラウンドではなく .NET プログラミングのバックグラウンドを持つ人にとっては)。また、ヒットすると IntelliSense も取得されます.。これは素晴らしいボーナスです。もちろん、これらの操作を拡張メソッドとして定義する必要があるため、ライブラリの設計をより慎重に検討する必要があります。

完全を期すために、拡張メソッドは次のように定義されています。

type System.String with
  member what.IsInfixOf(where:string) = 
    where.IndexOf(what, StringComparison.OrdinalIgnoreCase) >= 0 
  member x.TruncateAt(n) = 
    x.Substring(0, n)
于 2012-09-19T16:37:21.183 に答える
2
let (|<) f x = f x
let f = sprintf "%s%s"
let x = "A" |> f |< "B" |> f |< "C" //"ABC"
于 2012-09-19T16:23:12.917 に答える