하스켈 함수 구성 (.) 및 함수 적용 ($) 관용구 : 올바른 사용법


129

나는 Real World Haskell을 읽었 으며 끝이 가까워졌지만 스타일 문제는 (.)and ($)연산자 와 관련하여 저를 괴롭 혔습니다 .

다른 함수의 구성 인 함수를 작성할 때 다음과 같이 작성하십시오.

f = g . h

그러나 그 함수의 끝에 무언가를 적용하면 다음과 같이 작성합니다.

k = a $ b $ c $ value

그러나이 책은 다음과 같이 쓸 것입니다.

k = a . b . c $ value

이제, 그들은 기능적으로 동등 해 보입니다. 그들은 제 눈에서 똑같은 일을합니다. 그러나 내가 더 많이 볼수록 사람들이 책과 같은 방식으로 기능을 작성하는 것을 더 많이 볼 수 있습니다. (.)먼저 구성 하고 마지막에 사용 ($)하여 랏을 평가하는 값을 추가합니다 (많은 달러 작곡으로 아무도하지 않습니다) .

모든 ($)기호를 사용하는 것보다 훨씬 좋은 책을 사용하는 이유가 있습니까? 아니면 내가 얻지 못하는 모범 사례가 있습니까? 아니면 불필요한가요 전혀 걱정하지 않아도 되나요?


4
두 번째 예는 다음과 같이 수행 될 수 있습니다.k = a $ b $ c value
Thomas Eding

1
그렇습니다. Zifre가 아래에 언급했듯이 가능하지만 아무것도 해치지 않고 그의 (그리고 지금 당신의) 의견이 의미가 있기 때문에 그대로두기로 결정했습니다. 그래도 감사합니다. +1 :)
Robert Massaioli 1

2
또 다른 일반적인 방법은입니다 a . b $ c value. 세 번째 예만큼 좋아하지는 않지만 몇 문자를 절약합니다.
John L

답변:


153

나는 권위로부터 이것에 대답 할 수 있다고 생각한다.

모든 ($) 기호를 사용하는 것보다 훨씬 좋은 책 방식을 사용해야하는 이유가 있습니까?

특별한 이유가 없습니다. Bryan과 저는 둘 다 라인 노이즈를 줄이는 것을 선호합니다. .보다 조용합니다 $. 결과적 f . g . h $ x으로이 책은 구문을 사용 합니다.


3
글쎄, 나는 이것보다 더 나은 대답을 기대할 수 없다. 저자 자신 중 하나에서. :) 그리고 그것은 말이 되는대로 페이지에서 훨씬 조용하게 보입니다. 질문에 직접 답변하기 때문에 이것을 답변으로 표시하십시오. 답변 주셔서 감사합니다. 그리고 실제로, 책.
Robert Massaioli 2016 년

38
저자와 의견이 일치하지는 않지만, 그것을 사용 하는 대신 무언가 를 만드는 정신 모델에는 또 다른 중요한 이유가 있다고 생각 합니다. Haskell 사용자는 오히려 새로운 영리한 창조물로 생각하고 싶어합니다 . 이제 그들은 PHP 사용자처럼 사전 조립 된 함수 호출의 큰 사전을 연결하는 대신 익명의 새로운 함수를 호출했습니다. f.g.hf(g(h()))
Evan Carroll

1
흥미로운 사실은 '라인 노이즈 감소'와 '보다 조용합니다'입니다. 나는이 용어로 프로그래밍 언어에 대해 생각한 적이 없지만 완벽하게 이해된다.
Rabarberski

53

그것들은 실제로 동등합니다 : $연산자는 본질적으로 아무것도하지 않는다는 것을 명심하십시오 . f $ x로 평가됩니다 f x. 그 목적은 $고정 행동 (오른쪽 연관 및 최소 우선 순위)입니다. $접두사 우선 순위 대신 그룹화를 위해 괄호를 제거 하고 사용하는 코드 스 니펫은 다음과 같습니다.

k = a (b (c (value)))

k = (a . b . c) value

선호하는 이유 .오버 버전 $미적 매력 : 버전은 위의 매우 괄호 버전을 통해 모두를 선호에 대해 동일한 이유이다.

그럼에도 불구하고 일부는 괄호 대신 접두사 연산자를 사용하는 것이 Lisp와의 유사성을 피하려는 잠재 의식적 충동에 근거하고 있는지 궁금해 할 수 있습니다 (농담입니다 ... 생각합니까?).


38

내가 그의를 추가 할 것 f . g $ x, f . g의미있는 구문 단위입니다.

한편,에서 f $ g $ x, f $ g의미있는 단위가 아닙니다. 의 체인이 $틀림없이 더 필수적이다 - 최초 의 결과를 얻을 수 g의를 x, 다음f그것에, 다음 을 수행 foo여기에, 다음

한편, .일련의 함수를 구성하고 궁극적으로 무언가에 적용하면 데이터 체인 중심의 관점에 더 가까운 체인이 더 선언적 일 수 있습니다.


2
나는 Haskell을 배우고 있습니다 (의미있는 것을 코딩하지 않았습니다). 그러나 $를 일종의 "파이프"연산자로 생각하고 싶습니다. 터미널과 매우 비슷합니다. | 파이프 (데이터가 오른쪽에서 왼쪽으로 흐르는 것을 제외하고)이지만 터미널 프로세스와 마찬가지로 각 장치는 명시 적으로 독립적입니다.
LostSalad

1
$운영자는 유사하게 행동하는 것 같다 <|F 번호 연산자. 나는 실제로 F # (<|) a b = a b과 Haskell 에서 모두 동일하게 정의된다고 믿습니다 a $ b = a b.
Tom Galvin

@Quackmatic 메모리가 제공 (<|) b a = a b되는 [1; 2; 3; 4; 5] <| List.map ((+) 1)경우 처럼 사용되기 때문에 F #인지 확실 합니다.
BalinKingOfMoria Reinstate CMs

@BalinKingOfMoria <|연산자는 함수를 값에 전달하지 않고 함수에 값을 전달합니다 |>. 대신 코드 예제가 연산자 와 함께 작동 합니다.
Tom Galvin

@Quackmatic 아. 여러 버전이 있다는 것을 알지 못했습니다 (F #을 많이 사용하지 않았습니다).
BalinKingOfMoria Reinstate CMs

18

나를 위해, 나는대로 대답은, (a)는 깔끔함 생각 돈 말했다 ; (b) 코드를 편집 할 때 함수가 포인트 프리 스타일로 끝날 수 있다는 것을 알게되었습니다. 그런 다음 $돌아가고 모든 것을 변경하는 대신 마지막을 삭제하면 됩니다. 확실히 사소한 요점이지만 근사합니다.


네, 함수 구성으로 끝내고 싶다면 더 빠릅니다. :) 키 입력을 저장하는 데는 도움이되지만 시간이 더 중요합니다. +1
Robert Massaioli

13

이 haskell-cafe thread 에 대한이 질문에 대한 흥미로운 토론이 있습니다. 분명히 올바른 연관성 $"정확히 잘못되었다"고 주장하는 소수의 견해가 있으며 , 선택 f . g . h $ x하는 f $ g $ h $ x것이 문제를 회피하는 한 가지 방법입니다.


이봐, 그 문제에 대한 모든 토론을 찾았 어 정말 대단합니다. 지금 읽었습니다. +1
Robert Massaioli


$!"정확한"틀린 연관성 을 가지고 있음 을 주목하라 – 왜 $인가! 운영자 권리 협회? .
imz-Ivan Zakharyaschev

3

그것은 단지 스타일의 문제입니다. 그러나, 책이하는 방식이 나에게 더 의미가 있습니다. 모든 기능을 구성한 다음 값에 적용합니다.

당신의 방법은 이상하게 보이고 마지막 $은 불필요합니다.

그러나 실제로는 중요하지 않습니다. 하스켈에는 대개 같은 일을하는 많은 방법이 있습니다.


3
나는 마지막 $이 불필요하다는 것을 알지 못했지만 가지고 있어야합니다. 사람들이이 의견의 의미를 알 수 있도록 감사합니다.
Robert Massaioli

0

나는 이것이 매우 오래된 질문이라는 것을 알고 있지만 언급되지 않은 또 다른 이유가 있다고 생각합니다.

새로운 point-free function을 선언 f . g . h하면 전달한 값이 자동으로 적용됩니다. 그러나을 쓰면 f $ g $ h작동하지 않습니다.

필자가 작곡 방법을 선호하는 이유는 함수를 작성하는 좋은 방법으로 이어지기 때문이라고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.