2017-05-23 4 views
1

리더 모나드 사용법을 배우고 싶습니다. 불행히도 단지 적은 양의 예제 코드를 사용할 수 있습니다.Reader Monad를 (Int -> Int)와 함께 사용하는 방법?

환경 및 검색된 값이 Int 인 Reader를 만들고 싶습니다. ReaderT이 예상되기 때문에, 나는 오류가 발생

addStuff :: Reader Int Int 
addStuff = do 
    a <- (*2) 
    b <- (+10) 
    return (a+b) 

: 나는 시도

type IntRead = Reader Int Int 

코드는 이것이다 :이 같은 유형을 정의했다. Reader Monad를 사용하여 addStuff과 같은 기능을 만드는 방법은 무엇입니까? 이 기능에 환경을 어디에서 제공해야합니까?

+0

'ask'를 통해 함수를 매핑해야합니다 :'a <- (*2) <$> ask' – Lazersmoke

+0

고맙습니다,하지만 환경과 함께'addStuff'를 어떻게 호출 할 수 있습니까? 이 코드를 사용하면 오류가 발생합니다 :'addStuff 10' –

+0

그것은 당신의 라이브러리에 달려 있습니다. 'Reader a b -> a -> b'와 isomorphic 한 함수가 필요합니다. 일반적으로'runReader'라고 불립니다. – Lazersmoke

답변

4

당신은이 두 isomorphisms로 다시 독자들에게 기능을 변환 할 수 있습니다

reader :: (r -> a) -> Reader r a 
runReader :: Reader r a -> r -> a 

일예

addStuff :: Reader Int Int 
addStuff = do 
    a <- reader (*2) 
    b <- reader (+10) 
    return (a+b) 

다음 코드를 runReader addStuff 5으로 테스트 할 수 있습니다.

이것은 학습 목적으로 좋습니다. 더 심각한 코드의 경우에는 동형을 많이 사용하지 말고 대신 ask 또는 asks에 의존해야합니다. 예 :

addStuff :: Reader Int Int 
addStuff = (+) <$> asks (*2) <*> asks (+10) 

독자 추상화의 요점은 기본 기능에 대해 생각되지 않습니다 : 실용적 스타일을 사용하여 더 나은

addStuff :: Reader Int Int 
addStuff = do 
    x <- ask -- fetch the implicit Int value 
    let a = (*2) x 
     b = (+10) x 
    return (a+b) 

또는 더 나은

addStuff :: Reader Int Int 
addStuff = do 
    a <- asks (*2) -- fetch the implicit Int value, and apply the function 
    b <- asks (+10) 
    return (a+b) 

또는,. ask 프리미티브를 통해 액세스 할 수있는 읽기 전용 변수에 대한 액세스 권한을 가질 수 있습니다.

보통 마지막 단계에서 runReader을 사용하여 실제로 모나 딕 리더 작업을 사용합니다.

+0

더 나아질 수 있습니까? : O –

+1

"영리한"코드 또는 바로 가기에 대해서는 너무 걱정하지 마십시오. 학습하는 경우 기본 사항을 이해하면 더 중요합니다. 그것이 어떻게 작동하는지. 비록 실제 생산 코드를위한 좋은 스타일이 아니더라도 잠시 동안 두 개의 동형을 많이 사용한다면 괜찮습니다. – chi

+0

'addStuff = liftA2 (+) (* 2) (+ 10)' – amalloy