-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added List.foldlWhile function #89
base: master
Are you sure you want to change the base?
Conversation
Hey @AIRTucha , Could you elaborate about your use case a bit? In what kind of context would one be adding up gray scale values until they are 255?
|
Hey @Chadtech, I am sorry for a long response, I was a little bit busy. I might get you wrong, but all these functions are substitutes for recursion in some sense. So, as I said before, there are two cases:
list
|> takeWhile someFunction1
|> foldl someFunction2 someInitialValue The performance is improved by: prevention of an intermediate creation and lower number of function calls. It should also reduce a pressure on GC.
type alias Litre = Float
type alias Tank =
{ level: Litre
, volume: Litre
}
add2Tank tank bucket =
let
newLevel = tank.level + bucket
in
if tank.volume > newLevel then
Just newLevel
else
Nothing
buckets: List Litre
buckets =
[ 1.5, 1.2, 2.0 ]
tank = -- { level: 4.7, volume: 5 }
buckets
|> add2Tank { level: 0.4, volume: 5 } Of course, it can be easily done by recursion, but several times, I faced a situation when I want such a function. |
Hey @AIRTucha , sorry for the delay in my reply. Heres a comparison as I see it, between using recursion and type alias Tank =
{ level : Float
, volume : Float
}
buckets : List Float
buckets =
[ 1.5, 1.2, 2.0 ]
tank : Tank
tank =
{ level : 0.4
, volume : 5
}
-- Recursion
fillTank : List Bucket -> Tank -> Tank
fillTank buckets tank =
case buckets of
first :: rest ->
if first + tank.level > tank.volume then
tank
else
fillTank { tank | level = tank.level + first } rest
[] ->
tank
-- foldWhile
fillTank : List Bucket -> Tank -> Tank
fillTank buckets tank =
List.Extra.foldWhile addToTank tank buckets
addToTank : Bucket -> Tank -> Maybe Tank
addToTank bucket tank =
if first + tank.level > tank.volume then
Nothing
else
Just tank I see the recursive technique at least as good at the foldWhile technique. Here are a few disadvantages that I see in the 0 The |
Great example @Chadtech. Just wanted to chime in that in addition to hurting readability, using |
Wait a minute, you can eliminate foldl by the exact same way, can't you? Ok, another possible case, actually, it was one of the reasons I wrote it here. So, I was working on some kind of parser. One of the key places in my project was folding over lines, parsing of each of them a combining them together. Parsing of each next line was based on a result previous one, so if it fails it has to stop and output the successful part. I assume that there are some other case on which the same pattern can be applied. Anyway, it is "extra", I used to think that the main idea here is to collect and experimental features and see if people are going to use them. |
List.foldlWhile function seems to be useful in two practical cases:
Accumulation of pixels in a grey scale image is a good example of the function use case.