Just wondering whether this idea already exists somewhere / how performant it would end up being given the usage of row kinds and the need for type-level programming to prove that it’s type-safe.
Let’s say you have the following types:
type Rec =
{ count :: Int
, name :: String
, other :: String
}
type Example = Array Rec
You would like to use to write something like this because of its declarative easy-to-read nature.
getSpecificStuff
:: Array Rec
-> { maxCount :: Int, maxLength :: Int, value :: List String }
getSpecificStuff arrayRec =
let
totalCount = sum $ map (_.count) arrayRec
maxLength = max $ map (length <<< _.name) arrayRec
allValuesAsList = reverse $ foldl (flip Cons) Nil $ map (_.other) arrayRec
in { totalCount, maxLength, allValuesAsList }
However, you don’t want to iterate through the array multiple times. Rather, you would like to iterate through it once for performance without losing the declarative nature of this code.
So, you write something like this instead:
getSpecificStuff
:: Array Rec
-> { maxCount :: Int, maxLength :: Int, otherList :: List String }
getSpecificStuff =
buildFoldl
{ totalCount: sumWith (_.count)
, maxLength: maxWith 0 (length <<< _.name)
, otherList: {init: Nil, acc: flip Cons }
}
where
sumWith f = { init: zero, acc: \acc next -> acc + (f next) }
maxWith init f = { init, acc: \acc next -> max acc (f next) }
buildFoldl
:: forall f a.
. Foldable f
=> ?Some_Definition -> f a -> Record ?OutputRows
buildFoldl rec foldableThing =
-- pseudo code below!
let
result = foldl (\acc next -> ?stuff) rec foldableThing
in mapLikeFunction (_.acc) result
Assuming it’s even possible to type-check, would buildFoldl
even be performant considering all of the type class dictionaries being passed around?