It's true, glpk is not part of the haskell standard library. But solving a simple LP problem is easily done in a minute or two:
lp = execLPM $ do setDirection Max
setObjective objFun
leqTo (varSum ["x1", "x2", "x3"]) 100
leqTo (10 *^ var "x1" ^+^ 4 *& "x2" ^+^ 5 *^ var "x3") 600
leqTo (linCombination [(2, "x1"), (2, "x2"), (6, "x3")]) 300
varGeq "x1" 0
varBds "x2" 0 50
varGeq "x3" 0
setVarKind "x1" IntVar
setVarKind "x2" ContVar
main = print =<< glpSolveVars mipDefaults lp
The code in the blog post is just longer and more complicated because it's generating multiple constraints from code.The only reason my code doesn't look as simple as the above is because it's doing a lot more. For example, this line generates 9 constraints:
reservationConstraints loadPattern = [ linCombination [ (1.0, "reservation_" ++ k),
(-1.0, "reserved_" ++ k ++ "_" ++ p) ], 0.0 |
p <- (Map.keys loadPattern),
k <- reservationTypes ]
E.g.: reservation_heavy - reserved_heavy_morning <= 0
reservation_heavy - reserved_heavy_afternoon <= 0
reservation_heavy - reserved_heavy_evening <= 0
reservation_medium - reserved_medium_evening <= 0
....
If Mathematica is so easy, I'd love to see a significantly simpler version of the same problem written in it. But I have absolutely no idea how I'd write that simpler version.