The meaning of the expression 'f 7' in function 1) below is unclear to me. Unless I use function 3), which always evaluates to false, it always resolves to true. Which is to say, when I pass it function 2) and function 2) should resolve to false, i.e., when x <=0, the else branch--in this case the expression fn x => 3x*--fails to execute. I think there's probably something obvious that I'm missing... any hints would be greatly appreciated.
1)
fun double_or_triple f =
if f 7
then fn x => 2*x
else fn x => 3*x
fun st x = if x > 0 then true else false
fun always_false (x:int) = false;
Addendum:
Using #Simon Shine's method with function 2) makes it absolutely clear what's going on:
double_or_triple st 6
-> (if st 7 then fn x => 2 * x else fn x => 3 * x) 6
-> (if (if (7 > 0) then true else false) then fn x => 2 * x else fn x => 3 * x) 6
-> (if (if true then true else false) then fn x => 2 * x else fn x => 3 * x) 6
-> (if true then fn x => 2 * x else fn x => 3 * x) 6
-> (fn x => 2 * x) 6
-> 2*6
-> 12
Unless I use function 3), which always evaluates to false, it always resolves to true.
Take this example:
- fun is_even x = (x mod 2 = 0);
- double_or_triple is_even 2;
> val it = 6 : int
You can evaluate these things by hand for clarity:
double_or_triple is_even 2
~> (if is_even 7 then fn x => 2*x else fn x => 3*x) 2
~> (if (7 mod 2 = 0) then fn x => 2*x else fn x => 3*x) 2
~> (if (1 = 0) then fn x => 2*x else fn x => 3*x) 2
~> (if false then fn x => 2*x else fn x => 3*x) 2
~> (fn x => 3*x) 2
~> 3*2
~> 6
with ~> being a hand-made reduction.
Related
Is there any way to run name resolution on an arbitrary expression without running it? e.g. I would like to take an expression such as
quote
x = 1
y = 2*x + 1
z = x^2 - 1
f(x) = 2*x + 1
end
and be told that the names defined in the scope of this block are x, y, z, f and the names *, +, ^, - are pulled in from outside the scope of this block. Bonus points if it can tell me that there's a sub-scope defined in the body of f which creates it's own name x and pulls in + from an enclosing scope.
This question appeared in the Julia Zulip community
Thanks to Takafumi for showing me how to solve this on Zulip
We can get a list of locally defined names in the outermost scope of a julia expression like so:
ex = quote
x = 1
y = 2*x + 1
z = x^2 - 1
f(x) = 2*x + 1
end
using JuliaVariables, MLStyle
function get_locals(ex::Expr)
vars = (solve_from_local ∘ simplify_ex)(ex).args[1].bounds
map(x -> x.name, vars)
end
julia> get_locals(ex)
4-element Array{Symbol,1}:
:f
:y
:z
:x
and we can get the symbols pulled in from outside the scope like this:
_get_outers(_) = Symbol[]
_get_outers(x::Var) = x.is_global ? [x.name] : Symbol[]
function _get_outers(ex::Expr)
#match ex begin
Expr(:(=), _, rhs) => _get_outers(rhs)
Expr(:tuple, _..., Expr(:(=), _, rhs)) => _get_outers(rhs)
Expr(_, args...) => mapreduce(_get_outers, vcat, args)
end
end
get_outers(ex) = (unique! ∘ _get_outers ∘ solve_from_local ∘ simplify_ex)(ex)
julia> get_outers(ex)
6-element Array{Symbol,1}:
:+
:*
:-
:^
Logic:
eploy(list, constant)
if list is empty then
return:
0;
else
return:
(first_element + constant*eploy(rest_of_the_elements, constant)
I have written following code:
fun eploy(xs, x1:int) =
if null xs
then (0)
else (x::xs') => x + x1*eploy(xs',x1)
eploy([1,2],4);
If you want to do pattern matching then you need to use case:
fun eploy(xs, x1) =
case xs of
nil => 0
| x::xs' => x + x1*eploy(xs', x1)
You can also merge that into the function definition by using clauses:
fun eploy(nil, x1) = 0
| eploy(x::xs', x1) = x + x1*eploy(xs', x1)
This question already has answers here:
Value of bindings in SML?
(2 answers)
Closed 6 years ago.
Could someone please help. I don't get the sequence of evaluation here and how we got values of "ans". e.g. in the first example there's no value of y and I'm not sure whether this returns a pair or calls x ! (fn y => y x). It would be very helpful if you can Trace each expression.
val x = 1
val f = (fn y => y x)
val x = 7
val g = (fn y => x - y)
val ans = f g
val ans = 6 : int
=====================================
fun f p =
let
val x = 3
val y = 4
val (z,w) = p
in
(z (w y)) + x
end
val x = 1
val y = 2
val ans = f((fn z => x + z), (fn x => x + x + 0))
val ans = 12 : int
There are a few things which help make problems like this much clearer
when trying understand an alien function Lexical scoping works.
add in types to the parameters and return values without modifying the program, the compiler will tell you if you get it wrong...
replace anonymous functions with named ones.
rename variable bindings that have the same names but refer to different lexical scope.
remove variable bindings that only get used once.
binding a value to a name does not actually perform any computation,
so is merely for the benefit of the reader, if it is not doing that job
it merely serves to obfuscate, then by all means remove it.
fun f (y1 : int -> 'a) = y1 1 : 'a;
fun g (y2 : int) = 7 - y2 : int;
val ans : int = f g;
so g is given as a parameter to f, f calls g giving it the parameter x having the value 1 making y2 = 1, which g subtracts 7 - 1 returning 6.
the return value of g is an int, thus f's 'a type when g is applied to it is an int.
for the 2nd one clean it up a bit, I pulled the anonymous fn's out into their own and named values and call f (foo, bar) to make it more readable...
fun f p =
let val x = 3
val y = 4
val (z, w) = p
in (z (w y)) + x end
fun foo z = z + 1;
fun bar x = x * 2;
val ans = f(foo, bar);
Finally, we can get rid of the let values which are only used once
and replace the (z,w) = p with just (z, w) as a parameter to the function which should be much easier to follow
fun f (z, w) = (z (w 4)) + 3
fun foo z = z + 1;
fun bar x = x * 2;
val ans = f(foo, bar);
val ans = ((4 * 2) + 1) + 3
I'm trying to write a function in SML to compute the partial sum of an alternating harmonic series, and for the life of me I can't figure out why the compiler says one of the cases is redundant. I haven't used case statements before(or local, for that matter), but the order of these cases seems right to me.
local
fun altHarmAux (x:int, y:real) =
case x of
1 => 1.0
| evenP => altHarmAux(x-1, y - y/(real x))
| oddP => altHarmAux(x-1, y + y/(real x))
in
fun altHarmonic (a:int) = altHarmAux(a, real a)
end
Even if you have defined the two predicate functions somewhere, they can't be used in a case like that.
whatever you write on the left hand of => will be bound to the value you are matching on, thus the two last matches in your case will match the same input, rendering the last one useless, as the first one will always be used
You will have to apply your predicate function to the value directly, and then match on the result
local
fun altHarmAux (x, y) =
case (x, evenP x) of
(1, _) => 1.0
| (_ true) => altHarmAux(x-1, y - y/(real x))
| (_, false) => altHarmAux(x-1, y + y/(real x))
in
fun altHarmonic a = altHarmAux(a, real a)
end
or perhaps simpler
local
fun altHarmAux (1, _) = 1.0
| altHarmAux (x, y) =
altHarmAux (x-1, y + (if evenP x then ~y else y) / (real x))
in
fun altHarmonic a = altHarmAux (a, real a)
end
or
local
fun altHarmAux (1, _) = 1.0
| altHarmAux (x, y) =
if evenP x then
altHarmAux (x-1, y - y/(real x))
else
altHarmAux (x-1, y + y/(real x))
in
fun altHarmonic a = altHarmAux (a, real a)
end
let (++) f g x = f (g x) in
let f x = x + 1 in
let g x = x * 2 in
(f++g) 1;;
Is the above expression correct?
It seems to me that the above code should be just like defining f++g x = 2 * x + 1. Am I correct?
Your implementation of function composition is correct, since :
(g ∘ f)(x) = g(f(x)) for all x in X
according to wikipedia
I get :
- : int = 3
in ocamlktop