2012-12-31 2 views
1

"ed"와 같은 아주 간단한 편집기를 작성하려고합니다. 이 프로그램에서는 수행 할 작업에서 문자열 명령을 변환하는 컨트롤을 작성하기위한 매핑을 사용하려고합니다. 여기에 코드 조각입니다 :haskell에서 Data.Map을 사용하는 이상한 오류

commands :: Map String ([Handle] -> IO()) 
commands = fromAscList [ 
    ("o",\list -> print "Insert name of the file to be opened" >> getLine >>= \nomefile -> 
     openFile nomefile ReadWriteMode >>= \handle -> editor (handle:list)), 
    ("i",\list -> case list of { [] -> print "No buffer open" ; handle:res -> write handle } >> editor list), 
    ("q",\list -> if list == [] then return() else mapM_ hClose list >> return()) 
] 

editor :: [Handle] -> IO() 
editor list = do 
    command <- getLine 
    let action = lookup command commands 
    case action of 
    Nothing -> print "Unknown command" >> editor list 
    Just act -> act list 

문제는 내가 "O"를 입력 할 때 내가 어느 ghci 또는 실행 파일의 편집 기능을 실행할 때 내가 대신 메시지 "알 수없는 명령"을 얻을 수 있다는 것입니다 함수를 호출하여 파일을 엽니 다. map 대신 associative list를 사용하여 동일한 코드를 시도했으며,이 경우 작동합니다. 그래서 여기서 어떤 문제가있을 수 있습니까?

이상한 점은 ghci의 매핑 명령에서 키를 호출하면 문자열 "o"도 포함 된 목록을 반환한다는 것입니다.

사전 도움을 주셔서 감사합니다.

+1

Prelude hiding (lookup)을 가져 왔습니까? 어쨌든 그렇게하지 않으면 오류가 발생합니다. 나는 아직 문제가 보이지 않는다 ... 사건 전에 print 커맨드를 사용하여 재미있는 I/O 작업이 진행되고 있지 않다면 어떻게 할까? – luqui

+0

'getLine'은 후행 줄 바꿈을 포함합니까? –

+0

@Tinctorius, Noope – luqui

답변

6
commands :: Map String ([Handle] -> IO()) 
commands = fromAscList [ 
    ("o",_), 
    ("i",_), 
    ("q",_) 
] 

그러나

ghci> Data.List.sort ["o","i","q"] 
["i","o","q"] 

당신은 Data.Map에게 거짓말을했다, 그래서 필요한 불변을 만족하지 않은 Map을 건설했다. 따라서 요청이 잘못된 지점 (때로는) 아래로 보내 졌기 때문에 Map의 항목을 찾지 못했습니다.

+0

주문 감사의 문제 일뿐입니다. 왜 알고리즘을 사용하여 목록을 주문해야합니까? –

+4

'fromAscList'는 목록을 정렬해야합니다. 'fromList'를 사용했다면 효과가있었습니다. 'Map'은 키가 정렬되면 더 효율적으로 빌드 될 수 있습니다. 그래서'fromAscList'와'fromDistinctAscList'가 존재합니다. –

+0

멋지다, 다시 한번 감사드립니다. D –

관련 문제