2
$\begingroup$

Consider the standard function FoldList[]. There are two forms (at least):

FoldList[f, x, list]

and

FoldList[f, list]

A function like this can be defined by making two separate definitions:

f[a, b, c] := ...

f[a, b] := ...

However, is that the approved method, or is there some better mantra?

$\endgroup$
  • $\begingroup$ You only need the full definition once, the second can call the first: f[a_, b_] := f[a, First[b], Rest[b]] $\endgroup$ – Simon Woods Apr 20 '17 at 21:27
  • $\begingroup$ @SimonWoods So how would that work for the FoldList[] example? $\endgroup$ – Igor Rivin Apr 20 '17 at 21:31
  • 1
    $\begingroup$ @IgorRivin ... the exact same way? Clear[foldlist]; foldlist[f_, x_, list_] := FoldList[f, x, list]; foldlist[f_, list_] := foldlist[f, First[list], Rest[list]]? Could you perhaps clarify your issue? $\endgroup$ – MarcoB Apr 20 '17 at 21:43
  • $\begingroup$ @MarcoB Ah, I understand, Simon's answer was specifically for the fold example, and, as you say, it is all fine there. I was looking for a general guideline... $\endgroup$ – Igor Rivin Apr 20 '17 at 21:46
2
$\begingroup$

Here is a recursive definition of function that has the same behavior as FoldList.

f[func_, b_List] := f[func, b[[1]] , b[[2 ;;]]]
f[func_, b_, c_List] := fhelper[func, b, c, {b}]

fhelper[func_, b_, {}, rtn_] := rtn
fhelper[func_, b_, c_, rtn_] :=
  With[{nxt = func[b, c[[1]]]}, fhelper[func, nxt, Rest[c], Join[rtn, {nxt}]]]

Tests

Clear[g, a, b, c, d, e]
f[g, a, {b, c, d, e}]

{a, g[a, b], g[g[a, b], c], g[g[g[a, b], c], d], g[g[g[g[a, b], c], d], e]}

f[g, {a, b, c, d, e}]

{a, g[a, b], g[g[a, b], c], g[g[g[a, b], c], d], g[g[g[g[a, b], c], d], e]}

Of course, FoldList is implemented as an iterator and is more efficient than the above code. However, the above does show the argument patterns for implementing a function like FoldList.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.