F#でのゴルフのヒント


21

F#でゴルフをするための一般的なヒントは何ですか?私は、少なくともF#に特有のゴルフ問題全般のコーディングに適用できるアイデアを探しています(たとえば、「コメントの削除」は答えではありません)。回答ごとに1つのヒントを投稿してください。

回答:


9

可能な場合のfunction代わりに使用しmatchます。1文字の変数に対して6文字を保存します。

let f=function // ... (14 chars)

let f x=match x with // ... (20 chars)

また、パターンマッチを置き換えて、1文字を一貫して保存することもできます。

match a with|          // ... (13 chars)
a|>function|           // ... (12 chars)
(function| (* ... *))a // (12 chars)

8

まだ型を制約していない変数のメソッドを使用する必要がありますか?必要な型のリテラルと比較して、結果を破棄してその変数の型に注釈を付けます。

let f (x:string)=x.Length
let f x=x="";x.Length

7

可能な場合は、中置演算子に接頭辞表記を使用します-それらを使用する関数を定義する必要がなくなります。

たとえば、これを有効にできます:

List.map(fun i->i+2)[1;1;2;3;5;8]

これに:

List.map((+)2)[1;1;2;3;5;8]

1
ここで使ってくれてありがとう!
aloisdg回復モニカ言う

5

タプルの分解

変数を使用できない場合は、複数のlet式の代わりにタプル分解を使用します

let a,b ="",[]

の代わりに

let a=""
let b=[]

stdinからの読み取り

F#コアライブラリは、System.Console.Incalledのエイリアスを定義しstdinます。これらにより、入力を読み取ることができます。

// Signature:
stdin<'T> :  TextReader

msdnのTextReader

それがより短いという事実を除いて大きな利点Consoleは、システムを開く必要もありません

文字列の繰り返し

文字列は基本的にaですchar seq。これによりSeq.map、文字列を直接使用できます。理解に使用することも可能です[for c in "" do]

ミュータブル/参照セル

すべての読み取り操作にはセルを間接参照するための追加の文字が付属しているため、参照セルの使用は常に短くなるとは限りません。

一般的なヒント

  • 完全なmatch .. withインラインを書くことが可能です

    function|'a'->()|'b'->()|_->()
    
  • 英数字以外の文字の前後に空白を入れる必要はありません。

    String.replicate 42" "
    if Seq.exists((<>)'@')s then
    if(Seq.exists((<>)'@')s)then
    
  • 文字列にスペースを左または右に埋め込む必要がある場合は、[s] printf [n]フラグを使用できます。

    > sprintf "%20s" "Hello, World!";;
    val it : string = "       Hello, World!"
    

    Core.Printfモジュール



3

関数のイータ変換

私のソリューションの 1つでこのヒントをくれたLaikoniに感謝します

たとえば、大文字の場合は3、その他のすべての文字の場合は1の文字列を合計する関数を考えます。そう:

let counter input = Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1) input

イータ変換により、これは次のように書き直すことができます。

let counter = Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1)

前と同じ方法で呼び出されます:

counter "Hello world!" |> printfn "%i"

関数順合成演算子 >>

元の課題は、大文字の場合は3、小文字の場合は1の文字列を合計することであり、他のすべての文字は除外されるとします。

これを次のように書くことができます。

let counter input = Seq.filter Char.IsLetter input |> Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1)

前方構成演算子(>>)を使用して、2つの関数(Seq.filterおよびSeq.sumBy)を連結できます。イータ変換を使用すると、関数定義は次のようになります。

let counter = Seq.filter Char.IsLetter >> Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1)

Chris Smithは、>>彼のMSDNブログでオペレーターに関するすばらしい記事を書いています。


2

可能な場合Seqは以下よりも短いList

[[1];[2;3];[4];[5]|>List.collect
[[1];[2;3];[4];[5]|>Seq.collect

1文字短いです...




1

.NETを使用する

.NETには、多くの素晴らしいビルトインがあります。F#はそれらを使用できるので、忘れないでください!

例:

open System.Linq

役立つことがあります!


1

ラムダを使用してバイトを保存します。たとえば、これ:

let f x=x*x

次のように表現できます:

fun x->x*x


1

このmoduleキーワードは、繰り返し使用される場合にモジュール名を短縮するために使用できます。例えば:

Array.fold ...
Seq.iter ...
List.map ...

になることができる

module A=Array
A.fold ...
module S=Seq
S.iter ...
module L=List
L.map ...

これは、モジュールメソッドが繰り返し使用される(およびRequireQualifiedAccess修飾子があるため毎回完全な名前を付ける必要がある)より長いプログラムでより便利で、特に通常のCLR配列を使用する方が便利な場合(例:可変性) )F#seqまたはlist

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.