I am new to SML and am trying to create a function middle(lst) of type 'a list -> 'a which returns the middle element of a given list. I want to be able to do this without any pre-implemented functions of the form List.xyz...
I have found a way to do this, but I am using tl, which I believe is part of that pre-implemented list structure.
(* helper for middle *)
fun divvy(first,second) =
if null(tl second) orelse null(tl(tl(second))) then hd first
else divvy(tl first, tl(tl(second)));
(* get middle element in list *)
fun middle([a]) = a
| middle(lst) = divvy(lst,lst);
Is there a way to do this without using pre-implemented functions?
Use pattern matching for the helper as well.
fun divvy (x::_, [_]) = x
| divvy (x::_, [_,_]) = x
| divvy (_::xs, _::_::ys) = divvy (xs, ys)
The same program written with pattern-match
constructs...
val middle =
fn [] => NONE
| [x] => SOME x
| lst =>
let
fun pick _ [] = NONE
| pick [] _ = NONE
| pick (x::_) [e1] = SOME x
| pick (x::_) [e1, e2] = SOME x
| pick (_::ys) (p::q::rs) = pick ys rs
in
pick lst lst
end;
evalCode();
<pre id="code"> val middle = fn [] => NONE | [x] => SOME x | lst => let fun pick _ [] = NONE | pick [] _ = NONE | pick (x::_) [e1] = SOME x | pick (x::_) [e1, e2] = SOME x | pick (_::ys) (p::q::rs) = pick ys rs in pick lst lst end; </pre> <pre class="sml-input"> middle []; </pre> <pre class="sml-input"> middle [1]; </pre> <pre class="sml-input"> middle [1, 2]; </pre> <pre class="sml-input"> middle [1, 2, 3]; </pre> <pre class="sml-input"> middle [1, 2, 3, 4]; </pre> <pre class="sml-input"> middle [1, 2, 3, 4, 5]; </pre> <script src="https://unpkg.com/@sosml/interpreter@^1.5.0/build/interpreter.min.js"></script> <script> function evalCode() { try { let initialState = Interpreter.getFirstState(); const code = document.getElementById('code'); const inputs = document.querySelectorAll(".sml-input"); let interpretationResult = Interpreter.interpret(code.innerText, initialState); console.log(interpretationResult.state.toString({ stopId: initialState.id + 1 })); inputs && inputs.length && inputs.forEach(input => { interpretationResult = Interpreter.interpret(input.innerText, interpretationResult.state); console.log(interpretationResult.state.toString()); }); } catch (error) { console.error(error.name, "\n", error.message); } } </script>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.