2017-10-19 6 views
3

이 프로그램을 고려 게으른 평가 문제 :이드리스 -

module test 

import Effects 
import Effect.StdIO 

(>>==) : Maybe a -> Lazy (a -> Maybe b) -> Maybe b 
(>>==) Nothing (Delay map) = Nothing 
(>>==) (Just x) (Delay map) = map x 

nothing : String -> Eff (Maybe String) [STDIO] 
nothing s = do 
    putStrLn s 
    pure Nothing 

func : Maybe String -> String -> Maybe String 
func Nothing _ = Nothing 
func (Just s) t = Just (s ++ t) 

test : Eff() [STDIO] 
test = do 
    let m = !(nothing "a") >>== (func !(nothing "b")) 
    putStrLn "end" 

main : IO() 
main = run test 

>>==의 오른쪽 게으른 선언 !(nothing "a") 반환 Nothing 때문에, 나는 >>==의 오른쪽은 평가되지 않을 것으로 예상한다.

그러나 실제로는 평가를받을 않으며, 그 이유를 이해할 수 없다 ...

더 광범위하게

, 나는 아마 돌아 Eff 계산을 연결하고 내가 처음 Nothing

을받을 때 실행을 중지하기 위해 노력하고있어

답변

0

Desugar the! 표기법. 분명히

test = do 
    x <- nothing "a" 
    y <- nothing "b" 
    let m = x >>== (func y) 
    putStrLn "end" 

"A", "B", 및 "종료"모두가 인쇄됩니다 만, func 평가되지 않을 수 있습니다.

Maybe에 직접 적용하지 말고 >>==을 (임의의) Eff 값으로 지정해야한다고 생각합니다.

HTH는

+0

내가 실제로 원하는 것은 계산이' "B는"'인쇄되지 않습니다 것을 "A"'그래서'아무것도 후 중지한다는 것입니다. 나는'do' 표기법이'Maybe' 대신에'Eff'라는 틀린 문맥에서 작동하기 때문에 이런 일이 일어나지 않을 것이라고 생각합니다. 하스켈에서 나는 'MaybeT' 모나드 변압기를 사용하여이 문제를 해결할 것입니다. Idris와 비슷한 것이 있습니까? 의존성 유형이 내가 더 깨끗한 것을 할 수있게합니까? – marcosh

+0

'EXCEPTION()'효과를 추가하십시오. '아무 것도'raise()를 호출하지 마십시오. 이미 정의 된 핸들러가 있습니다. –