2017-12-26 21 views
0

재귀를 사용하여 두 목록의 합계를 찾는 함수를 작성하는 데 문제가 있습니다. 목록이 비어 있으면 Nothing 일 수 있습니다.어쩌면 재귀

다음과 같은 기능의 수학은 다음과 같습니다

Σw[i]x[i] 

w x는 동일한 길이의 INT 배열 여기에

내 작업 코드 : 여기

example :: [Int] -> [Int] -> Int 
example [] [] = 0 
example (x:xs) (l:ls) = ((x*l) + (example xs ls)) 

것은의 생각이다 내가 원하는 일 :

example :: [Int] -> [Int] -> Maybe Int 
example [] [] = Nothing 
example (x:xs) (l:ls) = Just((x*l) + (example xs ls)) 

감사

답변

4

여기에 의도가 무엇인지 짐작하겠습니다. 정확하게 읽는지 여부는 확실하지 않습니다. 두 입력 목록의 길이가 다른 경우 함수에서 Nothing을 생성하려고합니까?

"행복한"기본 사례는 첫 번째 시도와 마찬가지로 0이지만, Maybe으로 들어 봤습니다.

example [] [] = Just 0 

이리스트는, 길이가 다른 목록의 하나이 비어있는 경우를 포함 상황을 처리합니다. 이러한 경우를 포함하지 않는 비 철저 패턴 일치에 대한 컴파일러 경고를 받아야합니다.

example [] _ = Nothing 
example _ [] = Nothing 

마지막으로 두 개의 비어 있지 않은 목록이 있습니다. 그것은 MaybeFunctor이라는 사실을 활용, example xs ys 이상 우리가 fmap 추가, 제외하고는 오히려 추가를 적용하는 것보다 직접 example xs ys에, 첫 번째 시도에서 해당 라인처럼 많이 보인다.

example (x : xs) (y : ys) = fmap (x * y +) (example xs ys) 

사용 예제 : 당신이 라이브러리를 사용하기를 원한다면 그런데

λ> example [1,2] [3,4] 
Just 11 

λ> example [1,2] [3,4,5] 
Nothing 

safe는 한 줄이 점을 설정하기위한 좋은 선택이 될 것입니다.

import Safe.Exact 

example xs ys = fmap sum (zipWithExactMay (*) xs ys) 
+0

첫 번째 예제에서 왜 단 11 개를 얻지 않고 10 개를 얻지 않는 이유는 무엇입니까? – Soldalma

+1

@ Soldalma (1 * 3) + (2 * 4)를 계산하기 때문에. – Potato44

+0

좋아, 알았어. 어떤 경우에는 하스켈의 문법에 익숙하지 않다. – Soldalma

1

당신이 가까이있어하지만 example xs ls로 재귀 호출은 Maybe Int 반환하고, 마지막 줄에, (x*l + example xs ls에) 따라서 귀하의 오류를 IntMaybe Int을 추가 할 수 없습니다.

기본 합으로 0를 사용하여,이 경우에 대처하기 위해 fromMaybe을 사용할 수 있습니다

:

example [] [] = Nothing 
example xl yl = Just $ sum $ zipWith (*) xl yl 
:이 같은 것을 사용하여 명시 적으로 재귀를 피할 수 있습니다 (더 깔끔하게과)

example :: [Int] -> [Int] -> Maybe Int 
example [] []   = Nothing 
example (x:xs) (l:ls) = Just $ x * l + fromMaybe 0 (example xs ls) 
또는


패턴 일치가 비 한정적인 패턴입니다. 길이가 다른 두 목록은 패턴 일치 예외를 발생시킵니다.

+0

재귀 솔루션은 결국 빈 목록 케이스에 도달하므로 항상 Nothing을 반환합니다. – mschmidt

+0

@mschmidt 수정 해 주셔서 감사합니다. – hnefatl