Reputation: 13
There are two list in sml and I want to add one to another
val one = [1.1,2.2,3.3] : real list;
val two = [4.4,5.5,6.6] : real list;
The result should be [5.5, 7.7, 9.9].
I not sure I'm doing this right but basically I'm trying to pass this two list to a fun then do things like one[0] + two[0]
Is there any better way to do it? thanks~
Upvotes: 1
Views: 285
Reputation: 36611
SML lists are not typically accessed by index. A list is either empty or a value and a list. With this recursive definition we can have a list of any length. It also means we only need to operate on two cases to iterate over a list: the empty list, or a list with an element and another list.
Consider a map
function that maps a function f
to a list and returns another list.
fun map f [] = []
| map f (x::xs) = f x :: map f xs
We could add 1 to every element in an int list
with something like:
map (fn x => x + 1) [2, 3, 4]
Which would yield [3, 4, 5]
.
It's pretty straightforward to map over two lists.
fun map2 f [] [] = []
| map2 f (x::xs) (y::ys) = (* ... *)
Though this does not accommodate lists of differing lengths or how to handle them.
If you can figure this out, accomplishing your assigned task is a very straightforward application of map2
.
Upvotes: 2
Reputation: 21
The most concise solution is to use the ListPair.map
function:
ListPair.map Real.+ (one, two)
This solution discards the excess elements if one list is longer than the other.
Upvotes: 2
Reputation: 1782
How about following...
fun add_lists any [] = any
| add_lists [] any = any
| add_lists (a::bs) (c::ds): real list = (a + c) :: add_lists bs ds;
> val add_lists = fn: real list -> real list -> real list
> add_lists [] [];
> val it = []: real list;
> add_lists [1.0] [];
> val it = [1.0]: real list;
> add_lists [] [2.1];
> val it = [2.1]: real list;
> add_lists [1.3] [2.0];
> val it = [3.3]: real list;
> add_lists [1.1, 2.2] [3.2, 4.5];
> val it = [4.300000000000001, 6.7]: real list;
> add_lists [1.3] [2.7, 3.5];
> val it = [4.0, 3.5]: real list;
> add_lists [] [2.3, 3.2];
> val it = [2.3, 3.2]: real list;
> add_lists [1.2, 2.1] [];
> val it = [1.2, 2.1]: real list;
> add_lists [1.0, 2.0, 3.0] [4.0, 5.0, 6.0];
> val it = [5.0, 7.0, 9.0]: real list;
> add_lists [1.1,2.2,3.3] [4.4,5.5,6.6];
> val it = [5.5, 7.7, 9.899999999999999]: real list;
let initialState = Interpreter.getFirstState();
let interpretationResult = Interpreter.interpret('', initialState);
function eval_code(code) {
let input_provider = document.querySelector('#interpreter-input-provider');
let code_to_execute = (code || input_provider.value || '').trim() + ';';
if (code_to_execute) {
try {
interpretationResult = Interpreter.interpret(code_to_execute, interpretationResult.state);
console.log(interpretationResult.state.toString());
if (interpretationResult.warnings && interpretationResult.warnings.length) {
interpretationResult.warnings.forEach(warning => console.log('[Evaluation Warning]\n', warning.toString()));
}
} catch (error) {
console.error('[Evaluation Error]\n', error.message);
}
input_provider.value = '';
}
}
function eval_definition() {
const fun_definition = `fun add_lists any [] = any
| add_lists [] any = any
| add_lists (a::bs) (c::ds): real list = (a + c) :: add_lists bs ds;`;
eval_code(fun_definition);
}
function run_tests() {
const input_array = [
"add_lists [] [];",
"add_lists [1.0] [];",
"add_lists [] [2.1];",
"add_lists [1.3] [2.0];",
"add_lists [1.1, 2.2] [3.2, 4.5];",
"add_lists [1.3] [2.7, 3.5];",
"add_lists [] [2.3, 3.2];",
"add_lists [1.2, 2.1] [];",
"add_lists [1.0, 2.0, 3.0] [4.0, 5.0, 6.0];",
"add_lists [1.1,2.2,3.3] [4.4,5.5,6.6];"
];
input_array.forEach(input => eval_code(input));
}
eval_definition();
run_tests();
// interpretationResult = Interpreter.interpret('fun f y = x | f 10 = "???";', interpretationResult.state);
// console.log(interpretationResult.warnings);
#interpreter-input-provider {
display: block;
// min-width: 200px;
//min-height: 30%;
width: 90%
}
button {
width: 20%;
height: 3em;
cursor: pointer;
}
<script src="https://unpkg.com/@sosml/interpreter@^1.5.0/build/interpreter.min.js"></script>
<section id="interpretation-input">
<button id="eval-top" onclick="eval_code();">Eval</button>
<textarea id="interpreter-input-provider" rows="20">
</textarea>
<button id="eval-bottom" onclick="eval_code();">Eval</button>
</section>
<section id="interpretation-output">
</section>
<code id="fun-definition" hidden>
fun add_lists any [] = any
| add_lists [] any = any
| add_lists (a::bs) (c::ds): real list = (a + c) :: add_lists bs ds;
</code>
Upvotes: 0