I have a haskell function that attempts to solve this problem:
Write a function 'howSum(targetSum, numbers)' that takes in a targetSum and an array of numbers as arguments. The function should return an array containing any combination of elements that add up to exactly the targetSum. If there is no combination that adds up to the targetSum, then return null. If there are multiple combinations possible, you may return any single one.
What I have returns all possible combos of numbers.
The function works by creating a recursive tree where the first call has the total sum, target, and concatMap creates a branch for each number with the remaining sum needed. If this reaches a target of 0, the branch to get there was a combination of subtracting numbers from nums, meaning you can use numbers in the nums to sum to target. When returned the result with the value at that node is concatenated (to each sub-list).
From my testing the function works properly, but the memoization does not. I know now that the memo (Map object) is useless in my attempt, because it is immutable and separate calls to howSumMemo only get access to cashed values that are ancestors in the recursive tree. It would work if memo was a mutable and referenced (Which is not possible in Haskell).
import Data.Map (Map, member, findWithDefault, empty, insert)
howSumMemo :: Int -> [Int] -> Map Int [[Int]] -> [[Int]]
howSumMemo target nums memo
| target > 0 = findWithDefault val target $ insert target val memo
| target < 0 = []
| otherwise = [[]]
where val = concatMap (\x -> map (x :) (howSumMemo (target-x) nums memo)) nums
-- Memoized howSum
howSum target nums = howSumMemo target nums empty
-- Normal howSum
howSum' :: Int -> [Int] -> [[Int]]
howSum' target nums
| target > 0 = concatMap (\x -> map (x :) (howSum' (target-x) nums)) nums
| target < 0 = []
| otherwise = [[]]
How can I get the memoization to work for howSum? I've tried referencing https://wiki.haskell.org/Memoization.
Mapinto theconcatMap, or b) tie the know