I have question about “functional chaining”. Say, I have a list
myList: List[MyInput]
a) When I have a function
def myMapFunc (x:MyInput): MyData = ...
I can easily map over the list:
result: List[MyData] = myList.map(myMapFunc)
b) Now I have a function
def myChainfunc (x: MyInput, old: MyData): MyData
and I want to chain all the MyInput
elements in myList
via myChainfunc
. So for a 3-element myList I could write it out like this:
result: myData = myChainFunc(myList(2), myChainFunc(myList(1), myChainFunc(myList(0), startMyData)))...
How can I write this chain application for a general n-element list? And how can I do so functionally, i.e. without a for loop, but with some map-like operator?
In Haskell, I think, I would have used some sort of fold; what do I use in Scala 3?
Simple foldLeft would probably would be the most idiomatic:
trait Input
trait Data
def func(x:Input, old: Data): Data = ???
val inputs: Seq[Input] = ???
val initialState: Data = ???
inputs.foldLeft(initialState){case (state, input) => func(input, state)}
// or simply
inputs.foldRight(initialState)(func(_, _))
// which is the same as
inputs.foldRight(initialState){case (input, state) => func(input, state)}
3 Likes
foldRight
expects a function with that signature, so you can even write inputs.foldRight(initialState)(func)
, without wrapping it in a lambda. Also, the case
is usually not needed, unless the function is expected to accept a tuple.
As you mention Haskell, a tip if you know a function in Haskell, but can’t find the Scala equivalent: the Scala 3 documentation can search by signature, so you can find foldLeft with List[A] => B => ((B,A) => B) => B
(sadly, it requires the correct order of parameters, which sometimes differ from Haskell, so you may have to try several).
If you want to write purely functional code, you may also want to look into the libraries Cats or ZIO Prelude, which both add various functional abstractions and functions (the former being closer to Haskell).
3 Likes
@WojciechMazur Thanks for the details!
foldRight
worked out of the box the way func
was given.
However I need application the other way round and I can change the signature of func
, so that’s what I did and now it works directly with `foldLeft. 
How cool is that! Looks to me like a “Hoogle for Scala”.
Thanks for point it out to me. It will help me.