2012-11-17 3 views
21

두 인수의 하스켈 함수를 다시 작성해야합니까이 하스켈에 다음 함수은 어떻게 포인트 - 무료로 스타일을

나는 것 '관용적'하스켈을 작성하는 방법을 배우려고 노력하고있어
agreeLen :: (Eq a) => [a] -> [a] -> Int 
agreeLen x y = length $ takeWhile (\(a,b) -> a == b) (zip x y) 

괄호 대신 .$을 사용하는 것이 더 좋으며, 가능한 경우 무한 코드를 선호하는 것이 좋습니다. 나는 단지 xy을 명시 적으로 언급하는 것을 제거 할 수 없다. 어떤 아이디어?

두 인수의 함수를 pointfreeing하는 것과 동일한 문제가 있다고 생각합니다.

지금까지 좋은 코드를 작성하는 중입니다. 일부는 "숙제를하지 않고 점심을 버는 데 필요한 것을 사용하십시오."

감사합니다.


(추가 코멘트) 답변에 대한 감사합니다. 이 함수가 pointfree로부터 이익을 얻지 못한다고 당신은 확신했습니다. 그리고 여러분은 또한 변형 표현을 연습하기위한 훌륭한 예를 나에게 주셨습니다. 그것은 여전히 ​​나를 위해 어려운, 그리고 포인터 C.

+2

hlint (http://community.haskell.org/~ndm/darcs/hlint/hlint.htm)는 사용법을 비롯하여 표현을 작성하는 다른 방법을 배우는 데 매우 유용합니다. 및 $. – mhwombat

답변

41

가능하면 가능한 한 무료 코드를 선호합니다.

"가능한 경우"가 아니라 "가독성을 개선 한 곳 (또는 다른 명시 적 장점이있는 곳)"입니다.

는 지적-확보하기 위해

agreeLen x y = length $ takeWhile (\(a,b) -> a == b) (zip x y) 

첫 번째 단계는 당신이 (.)에있는 하나 ($) 오른쪽으로 이동하고 교체하는 것입니다 : 이제

agreeLen x y = length . takeWhile (\(a,b) -> a == b) $ zip x y 

을, 당신이 그것을 이동할 수 있습니다 심지어 더 오른쪽 :

agreeLen x y = length . takeWhile (uncurry (==)) . zip x $ y 

그리고 그곳에서 즉시자를 수 있습니다. 하나의 인자 떨어져

agreeLen x = length . takeWhile (uncurry (==)) . zip x 

는 그런 다음, 조성물 연산자 프리픽스 애플리케이션으로

agreeLen x = (.) (length . takeWhile (uncurry (==))) (zip x) 

그런를 재기록 할 수 있으며

F (GX)

같은

쓸 수

f . g $ x 
인수 x이 쉽게 제거되는
agreeLen x = ((.) (length . takeWhile (uncurry (==)))) . zip $ x 

을주는 일반적으로, 여기

f = (.) (length . takeWhile (uncurry (==))) 

g = zip와. 그런 다음 섹션에 (.)의 접두사 응용 프로그램을 변환하고

agreeLen = ((length . takeWhile (uncurry (==))) .) . zip 

를 얻을하지만, 그 원본보다 덜 읽을 수있는, 그래서 나는 일을하지 않는 것이 좋습니다 수로 표현의 변환을 실행 제외 지점이없는 그 스타일.

+9

정말 놀라운 점은 Schönfinkel이라는 사람이 1920 년에이 기법을 발명했기 때문입니다. –

11

에 당신은 또한 사용할 수 있습니다 그들이 하스켈에 필수적인 것 같다 :

agreeLen :: (Eq a) => [a] -> [a] -> Int 
agreeLen x y = length $ takeWhile id $ zipWith (==) x y 

개성있는 하스켈이 쉽게 읽을 무엇이며, 반드시 무엇이다 가장 포인트가없는.

+0

지퍼를 사용하면 훨씬 좋아 보인다. 그러나 "읽기가 더 쉽다"는 제 버전은 하스켈의 대부분의 작가 들과는 매우 다르기 때문에 제 버전을 자신의 것으로 더 가까이 옮기려고합니다. – JonathanZ

+3

@Jonathan 글쎄, 공동체조차도 스타일에 대한 의견이 다르긴하지만, 하나의 인수를 가진 함수 체인이있을 때마다 내 자신의 컨벤션이'.'를 사용한다는 것을 말할 수 있습니다. 그리고 두 개 이상의 인수를 사용한다면 그들. '$'에 관해서는 주로'do' 블록의 끝에서'foo $ do ... '와 같이 매달려있는 괄호를 없애거나 곱셈 - 중첩 된 괄호를 정돈하는 데 주로 사용합니다. –

관련 문제