2017-10-04 5 views
1

저는 하스켈의 초심자입니다. 두 개의 매개 변수가있는 함수를 만들려고 해요 : 문자와 문자열. 이 함수는 문자열을 살펴보고 주어진 문자가 문자열에 있는지 확인한 다음 문자열에있는 문자의 위치를 ​​나타내는 정수 목록을 반환합니다.하스켈 형식 불일치 Int 및 [Int]

내 코드는 다음과 같습니다 지능형리스트와 재귀 함수입니다

tegnPose :: Char -> String -> [Int] 
tegnPose c [] = [] 
tegnPose c (x:xs) = [if not (xs !! a == c) 
then [a] ++ tegnPose c xs 
else tegnPose c xs |a <- [0.. length xs - 1]] 

.

오류 내가 얻을 :

Uke4.hs:14:7: error: 
    * Couldn't match expected type `Int' with actual type `[Int]' 
    * In the expression: [a] ++ tegnPose c xs 
     In the expression: 
     if not (xs !! a == c) then [a] ++ tegnPose c xs else tegnPose c xs 
     In the expression: 
     [if not (xs !! a == c) then 
      [a] ++ tegnPose c xs 
     else 
      tegnPose c xs | 
      a <- [0 .. length xs - 1]] 
    | 
14 | then [a] ++ tegnPose c xs 
    |  ^^^^^^^^^^^^^^^^^^^^ 

Uke4.hs:15:7: error: 
    * Couldn't match expected type `Int' with actual type `[Int]' 
    * In the expression: tegnPose c xs 
     In the expression: 
     if not (xs !! a == c) then [a] ++ tegnPose c xs else tegnPose c xs 
     In the expression: 
     [if not (xs !! a == c) then 
      [a] ++ tegnPose c xs 
     else 
      tegnPose c xs | 
      a <- [0 .. length xs - 1]] 
    | 
15 | else tegnPose c xs |a <- [0.. length xs - 1]] 

나는 재귀 함수 단지를 통해 실행해야합니다 같은 불일치가 발생하는 방법을 이해하지 않습니다.

+1

목록 이해는 기본적으로 목록을 반환합니다. 아직 또 다른 목록을 반환하려고하면 원하는 목록이 아닌 목록이 제공됩니다. 나는 이해력을 완전히 피하기 위해 그것을 다시 쓰겠습니다. –

답변

5

불일치가 발생하는 이유는 다음과 같습니다. 첫째, 유형 [a]의 목록을 반환하는 지능형리스트 유형 a의 요소를 생성해야합니다, 그래서 당신이 일치하는 다음과 같은 필요 :

example :: [Int] 

-- .-- the final value is "[Int]" 
-- | 
example = [ 2+x*y | x <- [1..10], y <- [1..5], x < y] 
--   ^^^^^ 
--   | 
--   `- therefore, this must be "Int" 

당신의 예에서, tegnPose의 형태 서명을 의미하는 지능형리스트 [Int]을 반환하지만, 표현, 즉,리스트 요소를 생성해야합니다

if ... then [a] ++ tegnPose c xs else tegnPose c cx 

명확하게 돼있 일반 Int 길을 돌아 하지입니다.

제 에러 메시지가 표시된다 [Int]Int 있어야 전체 if .. then .. else 식의 결과를 예상 유형과 일치하지 않을 수있는 서브 표현식 [a] ++ tegnPos c xs의 실제 타입.

내가 제대로 질문을 이해한다면 (즉, 문자열에서 각 문자의 정수 위치의 목록을 반환 그래서 tegnPose 'a' "abracadabra" 반환 [0,3,5,7,10], 다음해야 중 하나 사용 재귀 또는 목록 이해, .

tegnPose c xs = [a | a <- [0..length xs - 1] 

거의 당신이 워싱턴 무엇을 수행합니다 있지만 두

주 비 재귀 지능형리스트 그 nt. 누락 된 부분은 상태를 테스트하여 위치 a에있는 문자가 c인지 확인하는 것입니다. 목록 중독에 "경비원"을 사용하는 것에 대해 모른다면, 그것을 살펴보십시오.

또는 지능형리스트없이 재귀 함수 :

tegnPose c (x:xs) = if (x == c) then ??? : tegnPose c xs 
           else tegnPose c xs 
tegnPose _ [] = [] 

거의는 현재 위치를 나타내는 숫자를 반환하는 ???의 장소에 배치하는 것을 분명 아니다 제외하고 당신이 원하는 것을.당신은 추가 매개 변수와 재귀 버전 작성하는 경우 :

tp n c (x:xs) = if (x == c) then n : tp (???) c xs 
          else tp (???) c xs 
tp _ _ [] = [] 

아이디어를 당신은 정의 할 수있는 :

tegnPose c xs = tp 0 c xs 

는 다음 가까운 것, 단지 당신이 어떤 새로운 가치를 알아낼 수 있다면 ??? 대신 n을 입력해야합니다.

더 많은 표준 하스켈 지퍼 같은 것들을 포함 할 수있는 솔루션 :

> zip [0..] "abracadabra" 
[(0,'a'),(1,'b'),(2,'r'),...] 

및 필터 :

> filter (\(i,c) -> c == 'a') $ zip [0..] "abracadabra" 
[(0,'a'),(3,'a'),...] 

및지도 :

> map fst $ filter (\(i,c) -> c == 'a') $ zip [0..] "abracadabra" 
[0,3,5,7,10] 

또는 수행하는 기능에 대한 Data.List에서 찾고 원하는 항목 :

> elemIndices 'a' "abracadabra" 
[0,3,5,7,10] 
+0

철저한 답변을 해주셔서 감사합니다. 나는 그것이 꽤 도움이된다는 것을 알았다 = ^) – TropicalOverflow

1

foldr과 함께이 기능을 구현하는 더 단순한 방법 일 수도 있습니다.

import Data.Bool (bool) 
charIndices :: Char -> String -> [Int] 
charIndices c = foldr (\t r -> bool r (fst t : r) (snd t == c)) [] . zip [0..] 

*Main> charIndices 't' "tektronix test and measurement instruments" 
[0,3,10,13,29,34,40] 

설명 :

foldr의 종류 그것은 세 가지 매개 변수를 Foldable t => (a -> b -> b) -> b -> t a -> b

이다; 두 파라미터

  • a
  • 유형 b의 하나의 값을 리턴 값을 보유 통과 가능한 데이터 유형 형 b의 초기 값을 받아

    1. 함수. 특히이 경우

      우리 형 a 값 및 정수 값 b[Int]의 목록 입력 t aString 형 (서명을 입력으로 인해)하게 Char 유형이다.

      첫 번째 매개 변수로 제공된 함수는 (\t r -> bool r (fst t : r) (snd t == c))이며 이는 Data.bool을 체크하면 매우 간단합니다. bool은 세 개의 인수를 취하는 a -> a -> Bool -> a 유형의 삼항 연산자입니다. 순서대로 그들은 부정적인 결과, 긍정적 인 결과와 조건입니다. (음수는 Haskell에서 평소처럼 왼쪽에있다.) 현재 문자가 대상 문자 c과 같은지 확인한 후 (r 결과를 의미)이 아닌 경우 fst t : r을 반환합니다. 마지막으로 t은 피플 투플리스트의 현재 튜플입니다. 튜플 목록은 zip [0..] s으로 구성되며 부분 적용으로 인해 함수 정의에 s이 표시되지 않습니다.

    +0

    이것은 나에게 더 단순 해 보이지 않는다. –

    +0

    @DanielWagner 나는 내 대답에 대한 설명을 첨부했다. – Redu