Sum two list in sml - sml

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~

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.

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.

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;
Test
> 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;
Illustration
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>

Related

Static casting between types for Generic nested records

Nested F# Record with generic type parameter, how do I statically cast between types in nested structure equivalent to traversing and performing 'T |> 'K, e.g. float |> int?
Currently I am Naively traversing the nested records and explicitly converting the type with from:float |> to:int or equivalently int(from). However, this is not very beautiful.
type Person<'T> = {Id : int; Value : 'T}
type Family<'T> = {Id : 'T; People : seq<Person<'T>>}
let fam1 = {Id = 1.0; People = [{Id = 1.1; Value = 2.9}; {Id = 1.2; Value = 4.4}]} : Family<float>
let fam2 = {Id = 2.0; People = [{Id = 2.1; Value = 3.9}; {Id = 2.2; Value = 5.4}]} : Family<float>
let partyFloat = seq{ yield fam1; yield fam2}
// In general, how to do this from a type T to a type K where conversion using T |> K will work
let partyInt : seq<Family<int>> = partyFloat
How to statically and/or
lazily convert to seq<Family<int>>?
In my real world case I have a DiffSharp D type that can be converted to a float with D |> float or float(D).
There is no magic way to cast the insides of types, you have to write your own.
It is idiomatic for F# and functional programming in general (and I personally recommend it, too) to write small functions for simple data transformations, and then assemble them together:
let mapPerson f p = { Id = p.Id; Value = f p.Value }
let mapFamily f fm = { Id = f fm.Id; People = Seq.map (mapPerson f) fm.People }
let mapParty f = Seq.map (mapFamily f)
let partyInt = mapParty int partyFloat
But of course you can do it in one big messy go:
let partyInt =
partyFloat
|> Seq.map (fun fm ->
{ Id = int fm.Id
People =
fm.People
|> Seq.map (fun p ->
{ Id = p.Id; Value = int p.Value }
)
}
)
It seems like what you are asking for are covariance ie that this should compile
let vs : obj list = ["1"; "2"]
F# doesn't support covariance (or contravariance) and probably never will. C# does however so you could write something like this
using System.Collections.Generic;
interface IPerson<out T>
{
int Id { get; }
T Value { get; }
}
interface IFamily<out T>
{
int Id { get; }
IEnumerable<IPerson<T>> Members { get; }
}
static class Program
{
static IFamily<string> CreateFamily()
{
return null;
}
static void Main(string[] args)
{
IFamily<string> familyOfString = CreateFamily();
IFamily<object> familyOfObject = familyOfString;
}
}
However, there's a functional pattern that could help us called polymorphic lenses.
(Picture from reddit thread: https://www.reddit.com/r/haskell/comments/2qjnho/learning_curves_for_different_programming/)
I used to think that polymorphic lenses isn't possible in F# due to the lack of higher-rank types. However, there's a hidden gem out there: http://www.fssnip.net/7Pk
Vesa Karvonen (IIRC he is also behind hopac so he's pretty cool) implements polymorphic lenses in F# using some pretty interesting tricks.
We can then map the inner values of an immutable structure reasonably easy.
let input : Family<int> =
{
Id = 1
Members = [{ Id = 10; Value = 123}; { Id = 11; Value = 456}]
}
printfn "%A" input
let output : Family<string> =
input
|> over Family.membersL (overAll Person.valueL ((+) 1 >> string))
printfn "%A" output
Full source code
// ----------------------------------------------------------------------------
// The code below taken from: http://www.fssnip.net/7Pk
// by Vesa+Karvonen - http://www.fssnip.net/authors/Vesa+Karvonen
// ----------------------------------------------------------------------------
type LensFunctor<'a> =
| Over of 'a
| View
member t.map a2b =
match t with
| Over a -> Over (a2b a)
| View -> View
type Lens<'s,'t,'a,'b> = ('a -> LensFunctor<'b>) -> 's -> LensFunctor<'t>
module Lens =
let view l s =
let r = ref Unchecked.defaultof<_>
s |> l (fun a -> r := a; View) |> ignore
!r
let over l f =
l (f >> Over) >> function Over t -> t | _ -> failwith "Impossible"
let set l b = over l <| fun _ -> b
let (>->) a b = a << b
let lens get set = fun f s ->
(get s |> f : LensFunctor<_>).map (fun f -> set f s)
let fstL f = lens fst (fun x (_, y) -> (x, y)) f
let sndL f = lens snd (fun y (x, _) -> (x, y)) f
// ----------------------------------------------------------------------------
// The code above taken from: http://www.fssnip.net/7Pk
// by Vesa+Karvonen - http://www.fssnip.net/authors/Vesa+Karvonen
// ----------------------------------------------------------------------------
let overAll l f = List.map (over l f)
open Lens
type Person<'T> = { Id : int; Value : 'T }
module Person =
let idS i p = { p with Id = i }
let valueS v { Id = i } = { Id = i; Value = v }
let idL f = lens (fun {Id = i } -> i) idS f
let valueL f = lens (fun {Value = v } -> v) valueS f
type Family<'T> = { Id : int; Members : Person<'T> list }
module Family =
let idS i f = { f with Id = i }
let membersS m { Id = i } = { Id = i; Members = m }
let idL f = lens (fun {Id = i } -> i) idS f
let membersL f = lens (fun {Members = m } -> m) membersS f
[<EntryPoint>]
let main argv =
let input =
{
Id = 1
Members = [{ Id = 10; Value = 123}; { Id = 11; Value = 456}]
}
printfn "%A" input
let output =
input
|> over Family.membersL (overAll Person.valueL ((+) 1 >> string))
printfn "%A" output
0

SML/NJ searching in list of tuples of list

I am very new to SML/NJ and I am kind of lost. I have been trying to implement a function that is going to search through the list of tuples that have some lists in it, for example:
val x = [(5, 2, [9 , 8, 7]), (3, 4, [6, 5, 0]), (11, 12, [8, 3, 1])]
I would like my function to add the first element of the tuple to the new list once there is a match between my target number and a number in element 3 of the tuple. I have tried several implementations, but none of them work properly so far.
type id = int* int* int list;
val b:id list = [(5,2,[9,8,7]), (3,4,[6,5,0]), (11, 12, [8,3,1])]
val number: int = 8;
val a: int list = nil;
fun findNum(nil) = a | findNum (x: id list) =
let val tem = hd(x)
val theList = #3tem
val i = #1tem
fun findMatch(nil) = a | findMatch(tem) =
if (number = hd(theList)) then i::a
else findMatch (tl(theList))
in findNum(tl(x))
end;
findNum(b);
I know it is badly written, and that is why it keeps returning an empty list. I feel like I need to do "if else" instead of let/in/end so it will recursively call the rest of the tuples in the list. My problem is that I am not sure how to do it because if I use if/else then I cannot declare some value inside the function. I appreciate any suggestions or hints.
Thank you.
You might start with a function member (x, xs) that is true if x is an element in the list xs:
fun member (x, xs) = List.exists (fn y => x = y) xs
A base case is when the list of three-tuples is empty. Then x does not occur in the third element of any of the (non-existing) three-tuples, and the list of results is empty. A recursive case is achieved by pattern matching against the first element of the list being a three-tuple, (i,j,xs), and the tail of the list, ts, and ask if x is a member of that third element xs; if it is, return the first part of the tuple, i:
fun find (x, []) = []
| find (x, (i,j,xs)::ts) =
if member (x, xs)
then i :: find (x, ts)
else find (x, ts)
A shorter version using the higher-order list combinators map and filter:
fun find (x, ts) = map #1 (filter (fn (i,j,xs) => member (x, xs)) ts)
Here is my implementation with some slight changes:
type id = int* int* int list;
val b:id list = [(5,2,[9,8,7]), (3,4,[6,5,0]), (11, 12, [8,3,1])]
val number: int = 8;
fun findNum [] = []
| findNum (x::xs) =
let
val theList :int list = #3 (x :id)
val i : int = #1 x
fun findMatch [] = false
| findMatch (y::ys) = if (number = y) then true
else findMatch ys
in
if (findMatch theList = true) then i ::(findNum xs)
else (findNum xs)
end;
Example:
- findNum b;
val it = [5,11] : int list

Match Non-exhaustive failure

I cannot figure out which case I am missing here,for my functions,can someone help me find which case to consider also so that I do not get the match non-exhaustive error.It is taking time for me to really figure out which part is missing.
fun eval_1 (nil,_) = nil
| eval_1 (_,nil) = nil
|eval_1 ((x::h::xs),(y::t::ys)) = if x = ~1 then (h,t)::eval_1(xs,ys) else(x,y)::eval_1(h::xs,t::ys);
fun eval_2 (nil,_) = nil
| eval_2 (x,nil) = nil
|eval_2 ((x),(y::ys)) = eval_1 (x,y)::eval_2(x,ys);
fun eval_3 (nil,_) = nil
| eval_3 ((x::nil),nil) = nil
| eval_3 ((x::xs),(ys)) = eval_2(x,ys)::eval_3(xs,ys);
Matching on (x:xs, y:ys) instead of ((x::h::xs),(y::t::ys)) gets rid of the non-exhaustive warning. To make the rest of the code equivalent you can use hd and tl from List to get the head of the tail and the tail of the tail instead of decomposing the list with x::next::xs.
fun eval_1 (nil,_) = nil
| eval_1 (_,nil) = nil
| eval_1 (x::xs, y::ys) = if x = ~1 then (hd xs, hd ys)::eval_1(tl xs, tl ys) else (x,y) :: eval_1(xs, ys)
fun eval_2 (nil,_) = nil
| eval_2 (x,nil) = nil
| eval_2 ((x),(y::ys)) = eval_1 (x,y)::eval_2(x,ys);
fun eval_3 (nil,_) = nil
| eval_3 ((x::nil),nil) = nil
| eval_3 ((x::xs),(ys)) = eval_2(x,ys)::eval_3(xs,ys);
Sample run:
> val eval_1 = fn : int list * 'a list -> (int * 'a) list
val eval_2 = fn : int list * 'a list list -> (int * 'a) list list
val eval_3 = fn : int list list * 'a list list -> (int * 'a) list list list
val it = () : unit
> eval_1([1,2,3], [4,5,6]);
val it = [(1, 4), (2, 5), (3, 6)] : (int * int) list

SML: Remove the entry from the List

How can I delete the element elem in list L? If the list does not contain elem, then the function should return the list unchanged.
For instance:
L = [1, 3, 4, 0, 5, 7]
elem = 5
So far I have the following function:
fun removeElem elem myList[] = myList
| removeElem (myList::tl) = if mem myList elem then
rm elem myList[]
else
removeElem elem tl
You can turn the question around and ask how to keep only those items not equal to elem. This fits cleanly with filter:
fun removeElem elem myList = filter (fn x => x <> elem) myList
This code will accomplish what you want to do: remove the element (actually it will remove all instances of the element if there are more than one) and return the rest of the list as-is:
fun remove_element (list, element) =
case list of
[] => []
| list_head::list_tail => let val a = remove_element(list_tail, element)
in
if list_head = element
then a
else list_head::a
end
fun delete (s,[]) = []
| delete (s,x::xs') =
if s = x then xs' (* more efficient than call delete function again *)
else x::delete(s, xs')
fun remove_element (elemlist, elem) =
case elemlist of
[] => []
| head::tail => if elem = head
then remove_element (tail, elem)
else head::remove_element (tail, elem)
Output SML/NJ:
val remove_element = fn : ''a list * ''a -> ''a list
val it = () : unit
(* matching *)
- remove_element ([1,2,3,4,5], 4);
val it = [1,2,3,5] : int list
(* non matching *)
- remove_element ([1,2,3,4,5], 7);
val it = [1,2,3,4,5] : int list
(* multiple instances *)
- remove_element ([1,3,4,4,5],4);
val it = [1,3,5] : int list
With no libraries or extra functions
fun remv(L, c) =
if null(L) then nil
else if c=hd(L) then remv(tl(L), c)
else hd(L)::remv(tl(L), c);
You can try this code.
fun remove_element (elemlist:int list, elem:int) =
case elemlist of
[] => []
| head::tail => if elem = head
then remove_element (tail, elem)
else head::remove_element (tail, elem)
also you can use this function to remove duplicate entries from a list:
fun remove_duplicates(xs: ''a list) =
let
fun helper(ds: ''a list, m: ''a) =
if null ds
then []
else if hd ds = m
then helper(tl ds, m)
else hd ds :: helper(tl ds, m)
in
if null xs
then []
else hd xs :: remove_duplicates( helper(tl xs, hd xs) )
end

Doing a N-dimensional walk in pure functional ML?

The idea is to walk over multiple dimensions, each one defined as a range
(* lower_bound, upper_bound, number_of_steps *)
type range = real * real * int
so functions like fun foo y x or fun foo z y x could be applied to the whole square XY or cube XY*Z.
SML/NJ doesn't like my implementation below :
test2.sml:7.5-22.6 Error: right-hand-side of clause doesn't agree with function result type [circularity]
expression: (real -> 'Z) -> unit
result type: 'Z -> 'Y
in declaration:
walk = (fn arg => (fn <pat> => <exp>))
Here's the code :
fun walk [] _ = ()
| walk (r::rs) f =
let
val (k0, k1, n) = r
val delta = k1 - k0
val step = delta / real n
fun loop 0 _ = ()
| loop i k =
let in
walk rs (f k) ; (* Note (f k) "eats" the first argument.
I guess SML doesn't like having the
type of walk change in the middle of its
definition *)
loop (i - 1) (k + step)
end
in
loop n k0
end
fun do2D y x = (* ... *) ()
fun do3D z y x = (* ... *) ()
val x_axis = (0.0, 1.0, 10)
val y_axis = (0.0, 1.0, 10)
val z_axis = (0.0, 1.0, 10)
val _ = walk [y_axis, x_axis] do2D
val _ = walk [z_axis, y_axis, x_axis] do3D
Is this kind of construct even possible ?
Any pointer welcomed.
Is walk expressible in ML's type system?
val walk : range list -> (real -> real -> unit) -> unit
val walk : range list -> (real -> real -> real -> unit) -> unit
The same one value cannot possibly exist with both those types in ML.
We can easily generate values for each of the desired types, though.
type range = real * real * int
signature WALK =
sig
type apply
val walk : range list -> apply -> unit
end
structure Walk0 : WALK =
struct
type apply = unit
fun walk _ _ = ()
end
functor WALKF (Walk : WALK) : WALK =
struct
type apply = real -> Walk.apply
fun walk ((low, high, steps)::rs) f =
let fun loop i =
if i > steps then () else
let val x = low + (high - low) * real i / real steps
in (Walk.walk rs (f x); loop (i + 1)) end
in loop 0 end
end
struture Walk1 = WALKF(Walk0)
struture Walk2 = WALKF(Walk1)
struture Walk3 = WALKF(Walk2)
With this, the following values exist with the desired types.
val Walk0.walk : range list -> unit -> unit
val Walk1.walk : range list -> (real -> unit) -> unit
val Walk2.walk : range list -> (real -> real -> unit) -> unit
val Walk3.walk : range list -> (real -> real -> real -> unit) -> unit
Then you only need to write
val _ = Walk2.walk [y_axis, x_axis] do2D
val _ = Walk3.walk [z_axis, y_axis, x_axis] do3D
To use the same walk for every dimensionality, you need it to use the same type for every dimensionality.
fun walk nil f = f nil
| walk ((low, high, steps)::rs) f =
let fun loop i =
if i > steps then () else
let val x = low + (high - low) * real i / real steps
in (walk rs (fn xs -> f (x::xs)); loop (i + 1)) end
in loop 0 end
Because the type is changed to
val walk : range list -> (real list -> unit) -> unit
your usage also has to change to
fun do2D [y,x] = (* ... *) ()
fun do3D [z,y,x] = (* ... *) ()
fun walk lst f = let
fun aux rev_prefix [] = f (rev rev_prefix)
| aux rev_prefix (r::rs) = let
val (k0, k1, n) = r
val delta = k1 - k0
val step = delta / real n
fun loop 0 _ = ()
| loop i k = (
aux (k+step :: rev_prefix) rs;
loop (i - 1) (k + step)
)
in
loop n k0
end
in
aux [] lst
end
fun do2D [x,y] = print (Real.toString x ^ "\t" ^
Real.toString y ^ "\n")
fun do3D [x,y,z] = print (Real.toString x ^ "\t" ^
Real.toString y ^ "\t" ^
Real.toString z ^ "\n")
val x_axis = (0.0, 1.0, 10)
val y_axis = (0.0, 1.0, 10)
val z_axis = (0.0, 1.0, 10)
val () = walk [y_axis, x_axis] do2D
val () = walk [z_axis, y_axis, x_axis] do3D
Found this implementation for variable number of arguments. Not sure it applies but it looks quite ugly.