2010-03-19 4 views
1

나는 이것을 가지고 있지만 나는 오류가 발생했습니다 :목록에 Haskell에서 정확히 3 개의 항목이 있는지 어떻게 감지합니까?

-- test if a list contains exactly three characters 
test :: [Char] -> Bool 
test xs | [_ , _ , _] = True 
      | otherwise = False 
+0

필자는 '[_, _, _]'을 [[_, _, _]'에 훨씬 선호한다고 말해야합니다. – MatrixFrog

+0

어떤 오류가 있습니까? –

+0

여기에 나와있는 답변은 내가 원하는 것 이상입니다. 고맙습니다. – unj2

답변

12

패턴 매칭은 는 수직 막대의 측면을 왼쪽에 발생합니다. 따라서 : 바로 아래 노트

test :: [Char] -> Bool 
test [_, _, _] = True 
test _   = False 

Norman Ramsey 같이 (이것은 (긴) 유한리스트에 적용될 때 매우 비효율적이고, 무한리스트에 정지하지 않기 때문에)해야하고, 다음 코드 하지 강력한 대안 용액은 따라서 하지 사용할 수 :

test :: [Char] -> Bool 
test xs = length xs == 3 

또한, length xs == 0는 항상 null xs로 교체해야합니다.

편집 : 자연스럽게 발생하는 질문은 다음과 같습니다. 어떻게 일반화할까요? 목록이 정확히 n 요소인지 여부를 테스트하려면 어떻게해야합니까? 입력 값이 무한 할 수 있다면 어떨까요? 다음은 비용이 중 n 또는 — 중 작은 값 목록의 길이 솔루션 그리고 우리는 가능한 희망을 수있는 즉, 점근 적, 솔루션 등의 효율적위한 :

hasLength :: Int -> [a] -> Bool 
hasLength n []  = n == 0 
hasLength 0 (x:xs) = False 
hasLength n (x:xs) = hasLength (n-1) xs 

사용법 :

*Main> hasLength 3 [1..2] 
False 
*Main> hasLength 3 [1..3] 
True 
*Main> hasLength 3 [1..4] 
False 
*Main> hasLength 3 [1..] 
False 

이 함수를 음수 길이로 호출하는 것이 안전하지 않은 인 입니다. 목록이 무한대이면 함수가 종료되지 않고 목록이 유한이면 목록의 길이에 비례하는 비용으로 False을 반환합니다. 쉬운 수정은 n이 음수가 아닌지 미리 확인하는 것입니다 (첫 번째 호출에만 해당). 그러나이 수정은 코드를 추악하게 만듭니다.

+0

어! 나는 '길이'예에 이르기까지 너와 함께 있었다. 고전적인 초보자 실수에 너무 가깝습니다.'null xs '대신'length xs == 0'을 쓰십시오. –

+0

만약 당신이 환상적 이길 원한다면, 나는 point-free 형태가'test = (3 ==)이 될 것이라고 생각한다. 길이' – MatrixFrog

+0

@ 노먼 : 흠, 여기에 도움이되는 'null'은 무엇입니까? – Stephan202

관련 문제