I would like to know how to compare two function F(x) & G(x) in SML, which two functions must return the same value that f(x)==g(x), where 1<= x <= 100.
For example:
- fun f x = x*x;
val f = fn : int -> int
- fun g x = x+x;
val g = fn : int -> int
- iden f g;
val it = false : bool
- fun f x = x*x;
val f = fn : int -> int
- fun g x = if x<0 then 0 else x*x;
val g = fn : int -> int
- iden f g;
val it = true : bool
Since testing whether or not two functions (programs) are equal for all inputs is not computable, your iden function will likely have to take more parameters than just the two functions that its comparing.
In general, your iden will be:
- fun iden f g elem = f(elem) = g(elem)
val iden = fn : ('a -> ''b) -> ('a -> ''b) -> 'a -> bool
In your specific case, you would probably want to do something like this:
- fun iden f g = let
= fun iden_h f g (a, b) =
= if a > b then iden_h f g (b, a)
= else if a = b then f(a) = g(a)
= else f(a) = g(a) andalso iden_h f g (a+1, b)
= in
= iden_h f g (1, 100)
= end
val iden = fn : (int -> ''a) -> (int -> ''a) -> bool
-
- iden (fn x => x + x) (fn x => 2 * x);
val it = true : bool
- iden (fn x => x + x) (fn x => x * x);
val it = false : bool
Related
My old notes on ML say that
let (๐ฃโ, โฆ , ๐ฃโ) = (๐กโ, โฆ , ๐กโ) in ๐กโฒ
is a syntactic sugar for
(ฮป ๐ฃโ. โฆ (ฮป ๐ฃโ. ๐กโฒ)๐กโ โฆ )๐กโ
and that
let (๐ฃโ, ๐ฃโ) = ๐ก ๐กโฒ in ๐กโณ
is equivalent to
let ๐ฃ = ๐ก ๐กโฒ in
let ๐ฃโ = snd ๐ฃ in
let ๐ฃโ = fst ๐ฃ in
๐กโณ
where
each ๐ฃ (with or without a subscript) stands for a variable,
each ๐ก (with or without a sub- or a superscript) stands for a term, and
fst and snd deliver the first and second component of a pair, respectively.
I'm wondering whether I got the evaluation order right because I didn't note the original reference. Could anyone ((confirm or reject) and (supply a reference))?
It shouldn't matter whether it's:
let ๐ฃ = ๐ก ๐กโฒ in
let ๐ฃโ = snd ๐ฃ in
let ๐ฃโ = fst ๐ฃ in
๐กโณ
Or:
let ๐ฃ = ๐ก ๐กโฒ in
let ๐ฃโ = fst ๐ฃ in
let ๐ฃโ = snd ๐ฃ in
๐กโณ
Since neither fst nor snd have any side-effects. Side-effects may exist in the evaluation of ๐ก ๐กโฒ but that's done before the let binding takes place.
Additionally, as in:
let (๐ฃโ, ๐ฃโ) = ๐ก ๐กโฒ in ๐กโณ
Neither ๐ฃโ nor ๐ฃโ is reliant on the value bound to the other to determine its value, so the order in which they're bound is again seemingly irrelevant.
All of that said, there may be an authoritative answer from those with deeper knowledge of the SML standard or the inner workings of OCaml's implementation. I simply am uncertain of how knowing it will provide any practical benefit.
Practical test
As a practical test, running some code where we bind a tuple of multiple expressions with side-effects to observe order of evaluation. In OCaml (5.0.0) the order of evaluation is observed to be right-to-left. We observe tthe same when it comes to evaluating the contents of a list where those expressions have side-effects as well.
# let f () = print_endline "f"; 1 in
let g () = print_endline "g"; 2 in
let h () = print_endline "h"; 3 in
let (a, b, c) = (f (), g (), h ()) in a + b + c;;
h
g
f
- : int = 6
# let f () = print_endline "f"; 1 in
let g () = print_endline "g"; 2 in
let h () = print_endline "h"; 3 in
let (c, b, a) = (h (), g(), f ()) in a + b + c;;
f
g
h
- : int = 6
# let f _ = print_endline "f"; 1 in
let g () = print_endline "g"; 2 in
let h () = print_endline "h"; 3 in
let a () = print_endline "a" in
let b () = print_endline "b" in
let (c, d, e) = (f [a (); b ()], g (), h ()) in
c + d + e;;
h
g
b
a
f
- : int = 6
In SML (SML/NJ v110.99.3) we observe the opposite: left-to-right evaluation of expressions.
- let
= fun f() = (print "f\n"; 1)
= fun g() = (print "g\n"; 2)
= fun h() = (print "h\n"; 3)
= val (a, b, c) = (f(), g(), h())
= in
= a + b + c
= end;
f
g
h
val it = 6 : int
- let
= fun f() = (print "f\n"; 1)
= fun g() = (print "g\n"; 2)
= fun h() = (print "h\n"; 3)
= val (c, b, a) = (h(), g(), f())
= in
= a + b + c
= end;
h
g
f
val it = 6 : int
- let
= fun f _ = (print "f\n"; 1)
= fun g() = (print "g\n"; 2)
= fun h() = (print "h\n"; 3)
= fun a() = print "a\n"
= fun b() = print "b\n"
= val (c, d, e) = (f [a(), b()], g(), h())
= in
= c + d + e
= end;
a
b
f
g
h
val it = 6 : int
Be aware that, in OCaml, due to the (relaxation of the) value restriction, let a = b in c is not equivalent to (fun a -> c)b. A counterexample is
# let id = fun x -> x in id 5, id 'a';;
- : int * char = (5, 'a')
# (fun id -> id 5, id 'a')(fun x -> x)
Error: This expression has type char but an expression was expected of type int
#
This means that they are semantically not the same construction (the let ... = ... in ... is strictly more general that the other).
This happens because, in general, the type system of OCaml doesn't allow types of the form (โฮฑ.ฮฑโฮฑ) โ int * char (because allowing them would make typing undecidable, which is not very practical), which would be the type of fun id -> id 5, id 'a'. Instead, it resorts to having the less general type โฮฑ.(ฮฑโฮฑ) โ ฮฑ * ฮฑ, which doesn't make it typecheck, because you can't unify both ฮฑ with char and with int.
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
I am new to SML and I am trying to practice in SML type reference.I am trying to deduct the below types:
a)fun add42 x =x+42
b)fun comp F G = let fun C x = G(F(x)) in C end
c)fun compA42 x = comp add42 x
d)val foo = compA42 add42
e)fun compCompA42 x = comp compA42 x
I think the solutions for the first four is:
a)int->int
b)(a->b)->(b->c)->a->c
c)(int->a)->int->a
d)int->int
But I am a little bit confused about the last one.
Is there any hint to deduct the last type??
Thanks a lot.
Let's do this manually, step-by-step:
fun compCompA42 x = comp compA42 x
It's a function, so compCompA42 has type ฮฑ -> ฮฒ.
compCompA42's return value must be of the same type as comp compA42 x, i.e. ฮฒ = typeof(comp compA42 x).
We already now the most general type for comp:
(a -> b) -> (b -> c) -> a -> c
Now, we need to specialize it for the case when a -> b = typeof(compA42) and (b -> c) = ฮฑ:
a -> b = typeof(compA42) = (int -> d) -> int -> d. From this equation follows that a = int -> d and b = int -> d.
So, ฮฑ = b -> c = (int -> d) -> c and ฮฒ = typeof(comp compA42 x) = a -> c = (int -> d) -> c.
Finally, our most general type for compCompA42 is
ฮฑ -> ฮฒ = ((int -> d) -> c) -> (int -> d) -> c.
Observe that you can always make some SML interpreter (e.g., smlnj) show you types:
- fun compCompA42 x = comp compA42 x;
val compCompA42 = fn : ((int -> 'a) -> 'b) -> (int -> 'a) -> 'b
And it's the same type we've got manually (just rename d to 'a and c to 'b).
I'am trying to decrypt the return of calc function below but i'am very confused.
I have the f function that takes 3 ints and returns an int.
The calc fuction i think should return val calc : int -> int = <fun> because f has to take 3 ints, i'am giving it x and y so now it needs one more to return another int, the final result. Why it this logic not correct?
I can't make any sense of the actual output, specially with the polymorfic values when i forced parameters in f to be integers.
# let f (x : int) (y : int) (z : int) = x + y + z;;
val f : int -> int -> int -> int = <fun>
# let calc x y f = f x y;;
val calc : 'a -> 'b -> ('a -> 'b -> 'c) -> 'c = <fun>
In the expression let calc x y f = f x y;;, f is a locally-bound variable (calc binds x, y and then f) rather than the function you have defined before.
If you had written let calc x y = f x y;; then you'd have the expected result.
The function calc contains no reference to the functionf. There is an argument named f be it could be named g without changing anything: let calc x y g = g x y. If you want to use the function f you have defined above and not any function of the right type, you must not pass f as an argument, you should rewrite calc like this:
let f x y z = x + y + z
let calc x y = f x y
and then calc will have the type int -> int -> (int -> int) which is more commonly written as int -> int -> int -> int.
I'm confused about let polymorphism in OCaml.
Consider the following code:
A:
let f = (fun v -> v) in
((f 3), (f true))
B:
let f = (fun v -> v) in
((fun g ->
let f = g in
f) f)
C:
let f = (fun v -> v) in
((fun g ->
let f = g in
((f 3), (f true))) f)
For A and B, there is no problem. But for C, OCaml reports error:
Error: This expression has type bool but an expression was expected of type
int
So for A, when evaluating ((f 3), (f true)), f's type is 'a -> 'a,
for B, when evaluating let f = g in f, f's type is 'a -> 'a.
But for C, when evaluating ((f 3), (f true)), f's type is int -> int.
Why C's f doesn't have type 'a -> 'a?
I have difficulty in understanding the implementation of OCaml's
let polymorphism, I'll appreciate it a lot if anyone can give a concise
description of it with respect to the question.
Your code is unnecessarily confusing because you're using the same name f for two different things in B and also two different things in C.
Inside C you have this function:
fun g -> let f = g in (f 3, f true)
Again this is unnecessarily complicated; it's the same as:
fun g -> (g 3, g true)
The reason this isn't allowed is that it only works if g is a polymorphic function. This requires rank 2 polymorphism, i.e., it requires the ability to define function parameters that are polymorphic.
I'm not exactly sure what you're trying to do, but you can have a record type whose field is a polymorphic function. You can then use this record type to define something like your function:
# type r = { f : 'a . 'a -> 'a };;
type r = { f : 'a. 'a -> 'a; }
# (fun { f = g } -> (g 3, g true)) { f = fun x -> x };;
- : int * bool = (3, true)
# let myfun { f = g } = (g 3, g true);;
val myfun : r -> int * bool = <fun>
# myfun { f = fun x -> x };;
- : int * bool = (3, true)
The downside is that you need to pack and unpack your polymorphic function.
As a side comment, your example doesn't seem very compelling, because the number of functions of type 'a -> 'a is quite limited.