F #에서의 골프 팁


21

F #에서 골프를 할 때 어떤 일반적인 팁이 있습니까? 저는 F #에 다소 특정한 코드 골프 문제에 적용될 수있는 아이디어를 찾고 있습니다 (예 : "댓글 제거"는 답이 아닙니다). 답변 당 하나의 팁을 게시하십시오.

답변:


9

가능한 경우 function대신 사용하십시오 match. 1 문자 변수에 대해 6 문자를 저장합니다.

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

vs

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는 Reinstate Monica가

5

튜플 해체

변수를 사용할 수없는 경우 여러 let 표현식 대신 튜플 분해를 사용하십시오.

let a,b ="",[]

대신에

let a=""
let b=[]

stdin에서 읽기

F # 핵심 라이브러리에 대한 별명을 정의 System.Console.In라고합니다 stdin. 이를 통해 입력을 읽을 수 있습니다.

// Signature:
stdin<'T> :  TextReader

MSDN의 텍스트 리더

그것보다 짧다는 사실을 제외하고 큰 장점 Console은 시스템을 열 필요가 없습니다.

문자열을 반복

string은 기본적으로 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

함수를위한 ETA 변환

내 솔루션 중 하나 에서이 팁에 대해 Laikoni 에게 감사드립니다 .

예를 들어, 대문자는 3, 다른 모든 문자는 1로 문자열을 합산하는 함수를 생각해보십시오. 그래서:

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

에 의해 ETA 변환 이는 다음과 같이 다시 쓸 수있다 :

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)

정방향 구성 연산자 ( >>)를 사용하여 두 함수 ( Seq.filterSeq.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

하나의 문자가 짧습니다 ...


2

하나의 매개 변수와 튜플을 사용할 때 괄호를 피하십시오

let f = [(0,1);(1,4)]|>Seq.map(fst)
printfn "%A" f

쓸 수있다

let f = [0,1;1,4]|>Seq.map fst
printfn "%A" f

1
또한 튜플 주위에 ()가 필요하지 않습니다. let f = [0,1; 1,4] |> Seq.map fst
thinkbeforecoding

1
고맙습니다. 업데이트되었습니다.
aloisdg는


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.