2017-03-25 4 views
0
left :: [String]->[Char]->Char 
left [] _ = [] 
left (x:xs) (head xs) = x -- it says error at head 

나는 적절한 괄호를 사용하지만, 아직도 내가 목록과 같은 [["A"],["B"],["C"],["D"],["E"]]에서 이전 요소를 얻기 위해 노력하고있어, error.By 구문 분석하는 방식을 복용. 어쩌면 다른 실수가있을 수 있습니다. Pls 날 정정 해.구문 분석 오류가

두 번째 질문은 이전 요소를 이전 색인 문자로 선택하는 방법입니다. 이리스트 [[ ""J ","O ","H ","N "], ["A ","L ","I ","C ","E " ", 나는"H "를 얻을 것으로 기대하고 싶다. 제 말은 "C"는 제 2 요소의 4 번째 색인이고 "H"는 이전 요소의 3 번째 색인입니다. Thnx 사전에

+2

'head xs'는 패턴이 아닌 표현식입니다. 패턴에서는'[]'과':'와 같은 생성자와 변수 만 사용할 수 있습니다. – chi

+2

지금 당신이 달성하려고하는 것은 분명치 않은 vvery입니다. 8n과 출력을 보여주십시오. ghc가 제공하는 오류에 대해 알고 싶다면 정의 된 각 줄을 ghci에 넣고': t'를 사용하여 서명을 요청하십시오. @chi 언급 된 오류를 수정 한 후에 – epsilonhalbe

답변

2

잘 이해했다면 String의 목록에서 문자를 찾고 이전 색인의 문자를 이전 색인에서 반환하는 함수가 필요합니다. 같은

뭔가 :

f ["JOHN", "ALICE"] 'C' == 'H' 

먼저 당신이 Char 리터럴 간단한 하스켈에서 따옴표 ('A'), 큰 따옴표 ("ABC")와 String 리터럴로 구분되는 것을 알 필요가있다.

하스켈에서 String[Char]의 별명이므로 "ABC"['A', 'B', 'C']과 같습니다.

이것은 하스켈에서 다음과 같은 함수를 정의 할 수 없다고 말했습니다. f a a = stuff. GHC는 a이 여러 번 정의되었다고 불평 할 것입니다. 두 개의 인수에 속성이 있는지 확인하려면 guard patterns이 필요합니다.

그래서 나는 다음과 같이 첫 번째 함수를 작성합니다

left :: [String] -> String -> String 
left [] _ = "" 
left [x] _ = "" 
left (x1:x2:xs) str 
    | x2 == str = x1 
    | otherwise = left (x2:xs) str 

을 두 번째 질문의 경우 :

import Data.List 

f :: [String] -> Char -> Maybe Char 
f [] _ = Nothing 
f [a] _ = Nothing 
f (x1:x2:xs) c 
    | Just i <- elemIndex c x2 = Just $ x1 !! (i-1) 
    | otherwise = f (x2:xs) c 

참고 :

  • left는 경우 strMaybe String를 반환해야 찾을 수 없거나 첫 번째입니다. x1 실제로
  • 보통 하스켈에서 목록 매개 변수가 마지막
  • , currying을 허용 할 정도로 오래 경우
  • f은 확인하지 않습니다.

EDIT (Data.List 모듈에서) zip

다소 더 현명한 방법.

f :: [String] -> Char -> Maybe Char 
f [] _ = Nothing 
f [_] _ = Nothing 
f (x1:"":xs) c = f xs c 
f (x1:x2:xs) c = f' (zip x1 (tail x2)) 
    where f' [] = f (x2:xs) c 
      f' ((a,b):l) = if b == c then a else f' l 

이 버전은 충돌하지 않습니다. "(n + 1) 번째 문자열에서 (m + 1) 번째 문자가"c 인 동안 "n 번째 문자열에서 m 번째 문자 임."을 만족하는 첫 번째 문자를 반환합니다. 결과는 Maybe (Just 'H')로 래핑됩니다. 그렇지 않으면 Nothing을 반환합니다 (Maybe은 대략 Haskell의 nullable 유형 임).

zip ['a', 'b', 'c'] [1, 2] == [('a', 1), ('b', 2)] 

결과리스트의 크기가 최소의 하나이다 :

zip

쌍 중 하나 개의리스트에서 두리스트를 병합 함수이다. 그래서 예에서, 무슨 일 것입니다 : 당신은 그럼 그냥 확인해야

zip "JOHN" (tail "ALICE") == [('J','L'), ('O', 'I'), ('H', 'C'), ('N', 'E')] 

는 두 번째 문자가 검색된 하나입니다, 그리고 쌍의 첫 번째 문자를 반환합니다.

+0

정말 좋은 답변, 정말 고마워. 동일한 질문에 1 단계 더 나아갈 것입니다 : 만약 [C ","C ","C "], ["D ","D ","D " "]]. 위의 알고리즘이 두 가지 질문에서 모두 실패합니까? –

+0

또한 두 번째 코드에서 이러한 오류가 발생합니다. ex.hs : 5 : 17 : 오류 : 범위에없는 변수 : elemIndex :: Char -> 문자열 -> 어쩌면 Int ex.hs : 5 : 35 : 오류 : • 예상 유형 '어쩌면 Char'와 실제 유형 'Char'가 일치하지 않음 • 표현식 : (x1 !! (i - 1)) 'f'의 방정식에서 f (x1 : x2 : xs) c | 그냥 i <- elemIndex c x2 = (x1 !! (i - 1)) | 그렇지 않다면 = f (x2 : xs) c –

+0

오 예, 지금 수정해야합니다 ('Just' 생성자와'elemIndex'를위한 임포트를 추가했습니다). 함수 또는 해당 함수를 포함하는 패키지의 서명을 기억하지 못하면 [Hoogle] (https://www.haskell.org/hoogle/)을 사용하여 하스켈 용어를 찾을 수 있습니다. – Drestin

1

"이전"목록 요소에 액세스하려면 다른 재귀를 사용해야합니다. 예 :

foo [] = baseCase 
foo [x] = onlyOneElement x 
foo (x1:x2:xs) = use x1 x2 (foo (x2:xs)) 

foo [1,2,3,4,5]를 호출, 당신은 x1=1, x2=2에 액세스 할 수 있습니다. 재발시 x1=2, x2=3에 액세스 할 수 있습니다. 따라서 x2을 "현재"요소로 간주하고 x1을 이전 요소로 간주 할 수 있습니다.

+0

"사용 "물건. 재귀가 진행되는 동안 인덱스를 추적 할 수있는 방법이 있습니까? 만약 내가 조건에서 이전 elemtns에 대한 짝수/홀수 검사를하고 싶다면 무엇을 의미합니까? –

+0

짝수/홀수 색인 정보가 필요한 경우 우리가 짝수 색인에 있는지 여부를 나타내는 추가 부울을 전달할 수 있습니다. 그런 다음, 우리가 재귀 할 때마다, 우리는 그 부울을 무효화하여, 우리가 원하는대로 계속해서 참과 거짓 사이를 뒤집습니다. – chi

관련 문제