2014-02-07 2 views
1

트리 내부의 특정 노드를 검색하는 함수를 구현했습니다. 다음은 기능 그리고 그것은 작동합니다foldl 함수 안에 Writer Monad 추가 Haskell

searchTree :: String -> Tree String -> Bool 
searchTree value tree = 
    foldl (\acc x -> if value `elem` x then True else acc) False (levels tree) 


을 그리고, 나는 동일한 기능을 구현하기 위해 노력하고있어,하지만이 시간, 나는 작가 모나드를 추가 할. 이 중 하나가 작동하지 않고 컴파일러에서 "예상 유형 'Writer [String] Bool'을 실제 유형 'Bool'과 일치시킬 수 없습니다"-> 오류는 'return true'명령의 네 번째 줄에 있습니다.

searchTree :: String -> Tree String -> Writer [String] Bool 
searchTree value tree = 
    foldl (\acc x -> if value `elem` x then do 
     tell ["My logger message "] 
     return True else acc) return False (levels tree) 

미리 감사드립니다.

답변

4

당신은 return False 주위에 괄호가 누락되었습니다 :

searchTree :: String -> Tree String -> Writer [String] Bool 
searchTree value tree = 
    foldl (\acc x -> if value `elem` x then do 
     tell ["My logger message "] 
     return True else acc) (return False) (levels tree) 

팁 : 문제는 내가 유형을 오해하고있어 것을 할 수 있기 때문에, 난 항상 내 하드 코딩 타입 서명을 제거 찾을 같은 버그를 쉽게하기 위해. 이와 같은 경우에, 당신은 (일반적으로) 정말 대신 foldr를 사용하려면 않는 것이

Couldn't match expected type `Bool' with actual type `m0 a0' 
Expected type: a0 -> Bool 
Actual type: a0 -> m0 a0 
In the second argument of `foldl', namely `return' 
In the expression: 
    foldl (\acc x -> if value `elem` x then do 
     tell ["My logger message "] 
     return True else acc) (return False) (levels tree) 
+0

명확성을 위해 추가해야합니다. 명시 적 서명 서명을 수정하면 다시 입력하는 것이 좋습니다. –

1

주 : 유형 서명을 제거하는이 경우에 오류를 변경했습니다. 오른쪽 왼쪽으로 연결하는 것보다 더 효율적입니다에

searchTree :: String -> Tree String -> Writer [String] Bool 
searchTree value tree = 
    foldr (\x continue -> if value `elem` x then do 
     tell ["My logger message "] 
     return True else continue) (return False) (levels tree) 

이유는,이, (>>=)을 연결하는 대부분의 경우 (작가 모나드 포함), 최초의 elem value x에 전체 목록을 검사하지만, 멈추지 않을 것입니다되고 foldr은 GHC의 목록 융합과 호환되지만 foldl은 그렇지 않습니다.