2010-08-20 5 views
4

예상대로 다음 줄은 작동하지만, 내가 왜 조금 걱정 :하스켈 : 변수의 범위 바인드 기능 람다 표현식을 사용하여

:

getLine >>= \x-> getLine >>= \y-> return [x, y] 

이 범위를 괄호의 ​​추가 람다 표현식을 고려

getLine >>= (\x-> getLine) >>= (\y-> return [x, y]) 

return에 사용 된 경우 x의 범위가 아니기 때문에 두 번째 줄이 잘못되었으므로 만족 스럽습니다. 첫 번째 줄에서 x의 범위가 '유출'된 것처럼 보인 점에 대해 우려합니다.

'유출'이 나쁜 관행으로 간주됩니까? 나는 그것이 범위에 어떻게 남아 있었는지에 관해 혼란스럽고 \x -> getLine 표현 직후에 사라지지 않았다. 이 두 번째 람다 첫 번째 내부에 있음이 분명하게

getLine >>= (\x-> getLine >>= (\y-> return [x, y])) 

, 그래서의 변수를 액세스 그것은 아무 문제가 없습니다 : 올바르게 하스켈의 우선 순위 규칙에 따라 첫 번째 줄을 괄호로하면

+0

@ sepp2k에는 정답이 있습니다. 또한 실제로 괄호로 두 번째 줄을 작성하려고하면 "범위에 포함되지 않음"오류가 발생합니다. –

답변

12

괄호는 단순히 잘못 설정됩니다. 올바른 괄호

getLine >>= (\x -> getLine >>= (\y -> return [x, y])) 

따라서 x 신체에 정의 물론이다이다. 이 기능을 사용하면 다음과 같은 코드를 포맷 할 수 있기 때문에 특히 유용하다

참고 :

getLine >>= \x -> 
getLine >>= \y -> 
return [x, y] 

거의

do 
    x <- getLine 
    y <- getLine 
    return [x, y] 

하지만없는 특별한 구문입니다.

14

, 당신은 얻을 첫번째 람다.

0

return 표현의 x에 대한 참조는 closure으로 알려져있다. 함수형 프로그래밍 언어의 전형적인 특징입니다. 하스켈 (Haskell)과 같은 순수 함수형 프로그래밍 언어에서는 걱정할 필요가 없습니다. 아주 좋은 기능입니다. F # (및 C# 요즘)과 같은 '하이브리드'함수형 프로그래밍 언어에서는 클로저가 실제로 예기치 않은 동작을 초래할 수 있습니다.

+0

죄송합니다.이 질문을받지 않았습니다. – Dario

+0

묻지 않은 것은 무엇입니까? –

+3

오히려 나는 이렇게 말할 것입니다 : 그것은 문제를 해결하는 것 같지 않습니다. Dave는 일반적으로 클로저에 대해서는 묻지 않았고, 하스켈 이외의 다른 언어로 클로저에 대해서는 명확히하지 않았습니다. 그는 'x'가 클로저의 범위 내에있는 것처럼 보이지 않기 때문에 이것이 어떻게 적절히 구성된 클로저인지를 묻는 것처럼 보였습니다. –

2

하스켈 구문은 "최대 뭉크"규칙을 따릅니다. 각 구문 요소는 가능한 한 확장되어 더 이상 확장하지 않으면 오류가 발생합니다. "\x ->"의 범위를 끝까지 확장해도 문제가 없으므로 그게 효과가 있습니다.

관련 문제