@popovitsj tem uma boa inclinação.
O SML usa a correspondência de padrões para determinar qual versão da definição de função usar.
fun sqrt x s = if ((s*s) <= x) then s | sqrt x s = if (s*s) > x then sqrt x (s - 1);
É não determinístico e a SML não tem a instalação para voltar atrás e tentar outra definição se a que tenta falhar (ou seja, como o Prolog).
Nesse cenário, você pode apenas usar
fun sqrt x s = if s * s <= x then s else sqrt x (s-1);
Essa função é logicamente válida apenas se você estiver passando, um valor que, quando aprovado originalmente, falhará na expressão IF.
Não testei isso, mas acredito que deveria ajudar.