하스켈에서 원하는대로 할 수는 있지만 구문이 잘못되었습니다. add
함수는 정확하지만 plusList
은 올바르지 않습니다. 특히, 구문 [xs ys]
당신은 아마이 정확히 add
와 동일 패턴이 얼마나
plusList (xs:ys) = add xs + plusList ys
공지 사항을 원 하스켈에 패턴으로 이해되지 않는다? 형식 서명에서 정확히 원하는 것을 말하기는 어렵습니다. 형식에 Int
의 목록이 반환되지만 기능 본문에는 Int
만 반환된다고되어 있습니다. 전자를 원할 경우
plusList (xs:ys) = add xs : plusList ys
으로 달성 할 수 있습니다.하지만 정확히 map add
입니다. 대신 후자를 원한다면 위의 첫 번째 스 니펫을 사용하십시오.
당신이 두 번째 문제는이 하스켈 코드를 완벽하게 유효하고 법적 라인이지만, 당신이 원하는 것을하지 않을 것이다
plusList [[]] = 0
입니다. 알다시피, [] :: [[Int]]
과 [[]] :: [[Int]]
사이에 차이가 있습니다. 첫 번째는 Int
s의 빈 목록이고 두 번째는 Int
s의 빈 목록을 포함하는 목록입니다. length ([] :: [[Int]])
을 실행하면 0
이 표시되지만 length ([[]] :: [[Int]])
은 1이됩니다. 대신, 그냥 do
plusList [] = 0
add
의 패턴과 같습니다. 대신 [Int]
을 반환 plusList
를 원하는 경우,이 라인은 단지 우리가
plusList :: [[Int]] -> [Int]
plusList (xs:ys) = add xs : plusList ys
plusList [] = []
-- or just
-- plusList xs = map add xs
쉽게
plusList :: [[Int]] -> Int
plusList (xs:ys) = add xs + plusList ys
plusList [] = 0
그리고
되어 있습니다 그래서 두 버전
plusList [] = []
해야한다 그래도 할 수있는 방법. 첫째, add
은 내장 된 sum
함수에 불과하지만 Int
에 특화되어 있습니다. 그러나 내장형 sum
은 foldl
을 사용하기 때문에 효율성이 떨어집니다.이 함수형 프로그래밍에서 같은 일반적인 패턴이기 때문에 대신에, 당신은 foldr
및 foldl
함수를 사용하면 사용한 재귀의 종류를 일반화
add :: [Int] -> [Int]
add xs = foldr (+) 0 xs
와 빠른 변형을 구현할 수 있습니다. 전체 목록을 조작하는 대신 다음 값과 누적기를 함께 결합하는 함수, 초기 누적 값 및 누적 값을 제공합니다. 귀하의 경우 누산기는 값과 동일한 유형을 가지며, 이는 일반적입니다. foldl
과 foldr
의 차이점은 미묘합니다. 구현은 꽤 비슷해 보이지만, 하스켈의 게으름은 foldl
이 공간 누출과 효율성 문제를 가질 수 있음을 의미합니다. 왜 거기에 도달했는지 자세히 설명해줍니다. 당신이 목록의 목록을 요약하려는 경우
또한, 당신이 필요한 추가 단순히
plusList = add . map add
아무것도 고차 함수를 사용하여 수행 할 수없는 패턴이 잘못되기 훨씬 적은 구문과 일치 없습니다.
'foldr'과 'foldl'을 섞어서 사용한다고 생각합니다. 여기에'foldr'은 공간 누설을 가지고 있지만, 썽크가 아닌 스택 공간 (썽크가 실행되면 스택이 뒤 따른다.)이 있다고 생각한다. –