PureScript doesn’t have clear, specified evaluation or elaboration semantics. Typeclasses elaborate to additional code, where
=> is an additional function abstraction. During typechecking, the compiler elaborates something with this signature:
foo :: CBN String -> Unit
foo _ = unit
example = foo (someExpensive string)
example = foo (\_ -> someExpensive string)
CBN synonym includes a constraint (
CallbyName String => String). So it is implicitly eta-expanding the expression. There’s nothing really wrong with this, but it would also be appropriate to elaborate it to:
example = let v1 = someExpensive string in foo (\_ -> v1)
And it’s arguable that this may be “expected” under strict evaluation. I think it’s very unlikely for this to change, so I probably wouldn’t worry about it, but I think it’s worth specifying.
As far as optimizations go, you want to preserve evaluation semantics. Otherwise you’ll get “obvious” code that works or doesn’t work depending on what optimizations are run. For example this has happened in the past with a bad optimization rule for function composition, which did naive eta-abstraction. This resulted in code (in core libraries) that worked fine on the JS backend, but not others because of the way it used recursion. It did not preserve strict evaluation semantics and so allowed recursive code that breaks with the de-facto strict evaluation of unoptimized output.
With regards to removing dictionary arguments all together, you may get the opposite, where recursive code works fine under unoptimized code, but breaks if the arguments are removed.