2013-12-21 4 views
2

방금 ​​하스켈을 this wikibook에서 배우기 시작했고 운동 중 하나에 약간 문제가있었습니다.하스켈의 부분 함수 적용

특히, 다음은 내가 약간

parseNumber :: Parser LispVal 
parseNumber = (many1 digit) >>= (\n -> return $ Number . read $ n) 

내가 return $ Number . read이 같은 람다로 평가하지 않는 이유를 설명 할 수있는 사람을 기대했다 그것을 변경하지 않는 한 내가

parseNumber :: Parser LispVal 
parseNumber = (many1 digit) >>= (return $ Number . read) 

을 예상대로 작동하지 않습니다 함수는 부분적으로 함수 평가가 point free 스타일 코드에서 사용될 때 정확히 수행 할 것이라고 생각했기 때문에 두 번째 정의에서 명시 적으로 만든 함수입니다 (분명히 아닙니다!)

어떤 도움을 주셔서 감사합니다. 초보자의 모나드 문제가 아닙니다.

+1

'돌아옵니다. 번호. 읽기 '는 효과가있다. – Ingo

답변

4

이것은 단지 $이 어떻게 연관되는지에 대한 문제입니다. 근본적으로 $은 더 적은 괄호를 작성하기위한 연산자 일뿐입니다. 이는 표현식 끝에 괄호를 추가하는 것과 같습니다.

이 아이디어를 사용하여, 우리는 두 번째 예를 다시 작성할 수 있습니다 : 참고로

parseNumber = (many1 digit) >>= (\n -> return (Number . read (n))) 

을 괄호 원래 표현은 다음과 같습니다

parseNumber = (many1 digit) >>= (return (Number . read)) 

그래서 부분적인 응용 프로그램에 해당하는 사실입니다 :

parseNumber = (many1 digit) >>= (\n -> (return (Number . read)) n) 

기본적으로, 복수의 $은 예상 한 것과 다른 방식으로 연관됩니다.

+0

해답을 가져 주셔서 감사합니다. 연예계 - 결국 나는 일종의 구멍/자리 표시자를 어떻게 남겨 놓았는지 상상해 보았습니다. 지금은 어리석은 것처럼 보입니다. 내가 (+ 부분적으로 응용 프로그램을 가지고 있다면) 계획에서 이것을 상상할 때'((+) 1 2)'라고 생각 하겠지만'+'는 인자 ​​자체에 적용되지 않으므로'(+ 1 2)'를 얻습니다. 물론 괄호는 실제로'+ (1,2) '를 의미하므로 잘못 가고있는 부분 일 수도 있습니다 – user3125280

1

그것은 당신이 원하는 다음과 같습니다

parseNumber = (many1 digit) >>= (return . Number . read) 

또는 유형을 String -> Parser LispVal

을 가지고 기능을 필요로하면서 alteratively

parseNumber = (many1 digit) `fmap` (Number . read) 

Number . readString -> LispVal 그렇게 return $ Number . read의 유형 Parser (String -> LispVal) 수있는 기능입니다

+0

감사합니다.이 문제는 해결되었지만 내 질문에 대한 답변이 좋지 않다고 생각합니다. 'Parser (a -> b)'와'a -> Parser b'의 차이점을 보지 않음) – user3125280

3

정의로 이동 -

($) :: (a -> b) -> a -> b 
($) = id 

(.) :: (b -> c) -> (a -> b) -> (a -> c) 
(.) f g x = f (g x) 

이제

return $ Number . read = ($) return (Number . read) -- (.) has higher precedence 
         = return (Number . read) 

가지고 당신이있어 모나드는 Parser 모나드, 그래서이 다른 함수에 대한 파서를 반환하는 함수에 대한 분석 값 (많은 레이어를 결합하려고 추상화의!당신이 볼 때 참고, 마지막으로


\n -> return $ Number . read $ n = \n -> return . Number . read $ n -- definition of (.) 
           = return . Number . read   -- eta reduction 
을 수행하여 볼 수)

대신에, 당신이 원하는 것은 당신이 쓴 것과 동일하다

return . Number . read 

입니다 패턴

x >>= return . f 

이 c 항상

fmap f x -- or liftM f x 

즉 당신이 정말로 전혀 Monad 인스턴스를 사용하지 않는 것을 그것을 보여줍니다로 대체, 대신 약한 (그리고 더 일반적인) Functor 인스턴스입니다.

+0

철저한 대답, 고맙지 만 거기에 가장 빨리 도달하지 못했습니다. 내가 받아 들인 대답에 대해 설명했듯이, 문제는 내가 격차가 인수를 떠났다는 것을 상상했다. (하지만 함수형 언어에서는 리턴의 유일한 인수가 함수가 될 수 있기 때문에 어리석은 것이다.) 그래서 받아 들인 대답이 더 도움이되었다. – user3125280