As Tayacan says, variables are not mutable in SML. If you want mutability you need to use reference types -- but usually, they are best avoided and it's preferable to stick to functional style.
It's also worth noting that your function is going to be very inefficient (O(n^2)), because of your use of list concatenation and length
on every iteration. And it is incorrect, because it will also remove stars in the middle of the string (and then redundantly go over the whole list a second time). Finally, your solution is far too complicated.
FWIW, here is the shortest implementation I can think of, using the Substring
library module and the function composition operator o
:
fun isStarOrSpace c = (c = #"*" orelse c = #" ")
val trimStars =
let open Substring
in string o dropl isStarOrSpace o dropr isStarOrSpace o full end
This does not use your shiftValue
because I don't understand what it's supposed to do. You can easily compute the number of removed characters by comparing the old and new string size. That is, your intended function (IIUC) could easily be expressed on top of mine as
fun trimStarsOnNode(s, shift) =
let val s' = trimStars s in (s', size s - size s' + shift) end
But to be honest, I don't understand what this version would be good for.
Edit: A version that returns the left drop count:
fun trimStars s =
let
open Substring
val ss = dropl isStarOrSpace (dropr isStarOrSpace (full s))
in
(string ss, #2(base ss))
end