On the following code the compiler extracts an intermediate variable from the subexpression after && that is always evaluated, causing List.hd to fail even though there is a check for it's length earlier in the expression.
let enableMidGameHunting = false;
let len = List.length;
let nearestGroots = [];
let isEmpty = x => List.length(x) == 0;
let flt = List.filter;
let d = (a, b) => 0;
let head = x => List.hd(x);
let mapWidth = 1920;
let oppHeroes = [0, 0];
let myMelees = [];
let oppMelees = [];
let bothHealthPct = 0.0;
let forwardOpp = 0;
let myTower = 0;
let myHeroesClose = [];
let myHeroes = [];
let huntGrootCondition =
enableMidGameHunting
&& len(nearestGroots) > 0
&& isEmpty(
flt(h => d(h, head(nearestGroots)) <= mapWidth / 3, oppHeroes)
)
&& (
len(myMelees) >= len(oppMelees)
|| bothHealthPct < 0.25
&& d(forwardOpp, myTower) <= mapWidth
/ 2
)
&& len(myHeroesClose) == len(myHeroes);
Js.log(huntGrootCondition);
Here's a minimal example:
let nearestGroots = [];
let isEmpty = x => List.length(x) == 0;
let oppHeroes = [0];
let huntGrootCondition =
List.length(nearestGroots) > 0
&& isEmpty(
List.filter(h => List.hd(nearestGroots) <= 1000, oppHeroes)
);
Js.log(huntGrootCondition);
Most helpful comment
Here's a minimal example: