I just started to learn F#. The book uses the following notation:
let name() = 3
name()
what that differs from this:
let name = 3
name
?
Before answering what () is lets get some basics defined and some examples done.
In F# a let statement has a name, zero or more arguments, and an expression.
To keep this simple we will go with:
If there are no arguments then the let statement is a value.
If there are arguments then the let statement is a function.
For a value, the result of the expression is evaluated only once and bound to the identifier; it is immutable.
For a function, the expression is evaluated each time the function is called.
So this value
let a = System.DateTime.Now;;
will always have the time when it is first evaluated or later invoked, i.e.
a;;
val it : System.DateTime = 1/10/2017 8:16:16 AM ...
a;;
val it : System.DateTime = 1/10/2017 8:16:16 AM ...
a;;
val it : System.DateTime = 1/10/2017 8:16:16 AM ...
and this function
let b () = System.DateTime.Now;;
will always have a new time each time it is evaluated, i.e.
b ();;
val it : System.DateTime = 1/10/2017 8:18:41 AM ...
b ();;
val it : System.DateTime = 1/10/2017 8:18:49 AM ...
b ();;
val it : System.DateTime = 1/10/2017 8:20:32 AM ...
Now to explain what () means. Notice that System.DateTime.Now needs no arguments to work.
How do we create a function when the expression needs no arguments?
Every argument has to have a type, so F# has the unit type for functions that need no arguments and the only value for the unit type is ().
So this is a function with one argument x of type int
let c x = x + 1;;
and this is a function with one argument () of type unit
let b () = System.DateTime.Now;;
Definitely do NOT think of () as some syntax for a function call or anything like that. It's just a value, like 3, 5, 'q', false, or "blah". It happens to be a value of type Unit, and in fact it's the only value of type unit, but really that's beside the point. () here is just a value. I can't stress that enough.
First consider
let name x = 3
What's this? This just defines a function on x, where x can be any type. In C# that would be:
int Name<T>(T x)
{
return 3;
}
Now if we look at let name () = 3 (and I somewhat recommend putting that extra space there, so it makes () look more a value than some syntactic structure) then in C# you can think of it as something like (pseudocode)
int Name<T>(T x) where T == Unit //since "()" is the only possible value of Unit
{
return 3;
}
or, more simply
int Name(Unit x)
{
return 3;
}
So we see that all let name () = 3 is, the definition of a function that takes a Unit argument, and returns 3, just like the C# version above.
However if we look at let name = 3 then that's just a variable definition, just like var name = 3 in C#.
In
let name() = 3
name()
name is a function, of type unit -> int.
In
let name = 3
name
name is an integer, of type int.
In F#, every function has an input type and an output type. The input type of let name() = 3 is unit, which has only one value (). Its output type is int, which has values from –2,147,483,648 to 2,147,483,647. As another example type bool has only two values, true and false.
So back to you question what's the usage of (). If you don't specify the input value of a function, it cannot get executed. So you have to specify an input value to your function let name()=3 to get it executed and because of its input type is unit, the only value you can use is ().
Here is another way to define the name function:
let name : (unit -> int) = (fun _ -> 3);;
and compare this to:
let name : int = 3
Using () creates a function which takes a paramter of type unit, rather than the second case which is just a simple integer.
This is particularly important when you want to control execution of the function.
The main difference is when you have
let name() =
printfn "hello"
1
vs
let name =
printfn "hello"
1
then
let t = name + name
will print "hello" once. But
let t = (name()) + (name())
will print "hello" twice.
You have to be careful with this when considering the order in which functions are evaluated.
Consider the following program:
let intversion =
printfn "creating integer constant"
1
printfn "integer created"
let funcversion() =
printfn "executing function"
1
printfn "function created"
let a = intversion + intversion
printfn "integer calculation done"
let b = (funcversion()) + (funcveriosn())
printfn "function calculation done"
This will print the following in order
creating integer constant
integer created
function created
integer calculation done
executing function
executing function
function calculation done
Related
I want to make a function that create a new variable, my goal is:
struct Test
setArg(varName,Float64,10.1,1.2)
end
That should return a struct Test with one argument varName from the Type Float64 with max 10.1 and min 1.2.
My problem is to know how to make the that function return a variable.
Or I'm thinking in another approach like this:
struct Test
varName::setArg(Float64,10.1,1.2)
end
here the function should just define a Type and max and min for the argument and that is okay, but I will prefer the first one if it is possible to do it in Julia.
So the question is how should my function/Type setArg look like?
You could create an incomplete mutable struct:
struct MyTest{T} #to allow different types while maintaining performance
min::T
max::T
val::T
valueset::Bool #to check if the struct is initialized
sym::Symbol #to access
end
to allow the user to access the value with the identifier provided, we overload Base.getproperty for the MyTest struct:
function Base.getproperty(val::MyStruct, sym::Symbol)
#identifier matches and the value was set
if val.sym==sym & val.valueset
return val.val
else
throw(error("oops")
end
end
finally, we make the struct with setArg:
function setArg(sym, type, min, max)
min = convert(type, min)
max = convert(type, max)
dummyval = zero(type) #
return MyTest(min, max, dummyval, false, sym)
end
finally, we make a function that sets the value, by calling the struct:
function (val::MyTest)(value) #a functor
if val.min <= value <= val.max
val.val = value
val.valueset = true
else
throw(error("out of bounds"))
end
return val
end
I imagine that the usecase is something like this :
constructor = setArg(:myname, Float64, 0.2, 0.5)
val1 = constructor(0.4)
val2 = constructor(0.5)
val3 = constructor(0.6) #error
val2.myname == 0.5
Is it possible in F# to apply a value as though it is a function? For example:
let record =
{|
Func = fun x -> x * x
Message = "hello"
|}
let message = record.Message // unsweetened field access
let unsweet = record.Func 3 // unsweetened function application
let sweet = record 3 // sweetened function application
Right now, the last line doesn't compile, of course:
error FS0003: This value is not a function and cannot be applied.
Is there some sort of syntactical sweetener that would allow me to "route" function application as I see fit, while still retaining its normal unsweetened behavior as well? I'm thinking of something magic like this:
// magically apply a record as though it was a function
let () record arg =
record.Func arg
(Note: I used a record in this example, but I'd be happy with a class as well.)
The closest thing I can think of would be a custom operator using statically resolved type parameters to resolve a specific property of type FSharpFunc, then invoke the function with the supplied input parameter. Something like this:
let record =
{|
Func = fun x -> x * x
Message = "hello"
|}
let inline (>.>) (r: ^a) v =
let f = (^a : (member Func: FSharpFunc< ^b, ^c>) r)
f v
record >.> 3 // val it : int = 9
For all the progress I've made in F#, I still get lost in various of the constructor and deconstructor syntax.
I'm running a recursive simulation. One of the parameters is a function for the stopping condition. I have various possible stopping conditions to choose from. I make them all have the same signature. So I decide it would be nice, and educational, to lock down these functions to a custom type--so that not just any function that happens to match the signature can be sent:
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
I think I'm doing this right, from tutorials, having a type name and an identical constructor name (confusing...), for a single case discriminated union. But now I can't figure out how to apply this type to an actual function:
let Condition1 lastRet nextRet i fl =
true
How do I make Condition1 be of type StoppingCondition? I bet it's trivial. But I've tried putting StoppingCondition as the first, second or last term after let, with and without parens and colons. And everything is an error.
Thanks for the patience found here.
EDIT:
I'll try to synthesize what I lean from the four answers (as of this moment), all good:
Trying to mimic this pattern:
s : string = "abc"
I was trying to write:
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
let condition1 lastRet nextRet i fl : StoppingCondition = // BAD
//wrong for a type alias, totally wrong for a union constructor
true
//or
let condition1 : StoppingCondition lastRet nextRet i fl = // BAD again
true
or other insertions of : Stopping Condition (trying to prefix it, in the way that constructors go, in that one line).
Now I see that to get what I was getting at I would have to do:
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
let conditionFunc1 lastRet nextRet i fl = //...
true
let stoppingCondition1 = StoppingCondition conditionFunc1
//or
let stoppingCondition2 = StoppingCondition <| (func lastRet nextRet i fl -> false)
//and there's another variation or 2 below
And what I didn't appreciate as a big negative to this approach is how a union type is different from a type alias. A type alias of string admits of the string functions when declared--it really is a string and does "string things. A single case discriminated union of string--is not a string any more. To have it do "string things" you have to unwrap it. (Or write versions of those functions into your type (which might be wrappers of the string functions).) Likewise a type alias of my function accepts those parameters. A DU of my function is just a wrapper and doesn't take arguments. So this doesn't work with discriminated union:
let x = stoppingCondition1 ret1 ret2 2 3.0 // BAD
//"stoppingCondition1 is not a function and cannot be applied"
And there's not enough value in my case here to work around the wrapper. But a type alias works:
type StoppingAlias = ReturnType -> ReturnType -> int -> float -> bool
let stoppingCondition:StoppingAlias = fun prevRet nextRet i x -> true
let b = stoppingCondition ret1 ret2 10 1.0 // b = true
I may not have everything straight in what I just said, but I think I'm a lot closer.
Edit 2:
Side note. My question is about defining the type of a function. And it compares using a type alias and a union type. As I worked at trying to do these, I also learned this about using a type alias:
This works (from: https://fsharpforfunandprofit.com/posts/defining-functions/ ):
type Adder = decimal -> decimal -> decimal
let f1 : Adder = (fun x y -> x + y)
//or
let f2 : decimal -> decimal -> decimal = fun x y -> x + y
but these are wrong:
let (f2 : Adder) x y = x + y // bad
let (f3 x y) : (decimal -> decimal -> decimal) = x + y // bad
let (f3 : (decimal -> decimal -> decimal)) x y = x + y // bad
And some discussion on this whole issue: F# Type declaration possible ala Haskell?
(And also, yeah, "assigning a type" isn't the right thing to say either.)
You don't "make it be of type" StoppingCondition. You declare a value of type StoppingCondition and pass Condition1 as the parameter of the DU case constructor:
let stop = StoppingCondition Condition1
That means, however, that every time you want to access the function contained in your single DU case, you have to pattern match over it in some way; that can become annoying.
You say you don't want just any functions that fulfill the signature to be valid as stopping conditions; however, it seems to be specific enough to avoid "accidentally" passing in an "inappropriate" function - with that, you could do something simpler - define StoppingCondition as a type alias for your specific function type:
type StoppingCondition = ReturnType -> ReturnType -> int -> float -> bool
Now you can use StoppingCondition everywhere you need to specify the type, and the actual values you pass/return can be any functions that fulfill the signature ReturnType -> ReturnType -> int -> float -> bool.
As has been said, you have to construct an instance of a StoppingCondition from an appropriate function, for example:
let Condition1 = StoppingCondition (fun _ _ _ _ -> true)`
One nice way to do this without weird indentation or extra parentheses is a backward pipe:
let Condition1 = StoppingCondition <| fun lastRet nextRet i fl ->
// Add function code here
The signature might be long enough to justify a record type instead of four curried parameters. It's a question of style and how it'll be used; the result may look like this:
type MyInput =
{ LastReturn : ReturnType
NextReturn : ReturnType
MyInt : int
MyFloat : float }
type StopCondition = StopCondition of (MyInput -> bool)
let impossibleCondition = StopCondition (fun _ -> false)
let moreComplicatedCondition = StopCondition <| fun inp ->
inp.MyInt < int (round inp.MyFloat)
To call the function inside a StopCondition, unwrap it with a pattern:
let testStopCondition (StopCondition c) input = c input
Specify the return type of a function is done like this:
let Condition1 lastRet nextRet i fl :StoppingCondition=
true
of course, this won't compile as true is not of the correct type.
I suspect the actual definition you want is closer to
let Condition1 :StoppingCondition=
true
though, as the type looks like it contains the function arguments.
Expanding on this, you can define such a function like:
let Condition1=fun a b c d -> StoppingCondition(fun a b c d -> whatever)
but this whole thing is pretty ugly.
Realistically, I think it is better to put all the functions in an array, which will force the types to match
So, it seems to me that you things you might want to with StoppingConditions are to create some predefined type of stopping condition.
Here are some examples of some possible stopping conditions:
let stopWhenNextGreaterThanLast = StoppingCondition (fun last next _ _ -> next > last)
let stopWhenLastGreaterThanLast = StoppingCondition (fun last next _ _ -> last> next)
(I've underscored the parameters I'm not using in my stopping condition definition)
Hopefully you can see that both of these values of type StoppingCondition.
Then you might want a function to determine if the stopping condition had been met given some parameters:
let shouldStop stoppingCond last next i value =
match stoppingCond with
|StoppingCondition f -> f last next i value
This function takes a stopping condition and the various states of your recursion and returns true or false depending on whether or not it should now stop.
This should be all you need to make use of this approach in practice.
You could extend this approach by doing something like this to cover multiple potential stopping conditions:
type StoppingCondition =
| StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
| Or of StoppingCondition * StoppingCondition
And modifying the shouldStop function
let rec shouldStop stoppingCond last next i value =
match stoppingCond with
|StoppingCondition f -> f last next i value
|Or (stp1, stp2) -> (shouldStop stp1 last next i value) || (shouldStop stp2 last next i value)
Now if we have a single condition, we stop when it's met or if we multiple conditions, we can check whether either of them are met.
Then you could Or together new stopping conditions from a base condition:
let stopWhenIIsEven = StoppingCondition (fun _ _ i _ -> i % 2 = 0)
let stopWhenValueIsZero = StoppingCondition (fun _ _ _ value -> value = 0.0)
let stopWhenIEvenOrValueZero = Or (stopWhenIIsEven, stopWhenValueIsZero)
I am trying to figure out the issue, and tried different styles that I have read on Scala, but none of them work. My code is:
....
val str = "(and x y)";
def stringParse ( exp: String, pos: Int, expreshHolder: ArrayBuffer[String], follow: Int )
var b = pos; //position of where in the expression String I am currently in
val temp = expreshHolder; //holder of expressions without parens
var arrayCounter = follow; //just counts to make sure an empty spot in the array is there to put in the strings
if(exp(b) == '(') {
b = b + 1;
while(exp(b) == ' '){b = b + 1} //point of this is to just skip any spaces between paren and start of expression type
if(exp(b) == 'a') {
temp(arrayCounter) = exp(b).toString;
b = b+1;
temp(arrayCounter)+exp(b).toString; b = b+1;
temp(arrayCounter) + exp(b).toString; arrayCounter+=1}
temp;
}
}
val hold: ArrayBuffer[String] = stringParse(str, 0, new ArrayBuffer[String], 0);
for(test <- hold) println(test);
My error is:
Driver.scala:35: error: type mismatch;
found : Unit
required: scala.collection.mutable.ArrayBuffer[String]
ho = stringParse(str, 0, ho, 0);
^one error found
When I add an equals sign after the arguments in the method declaration, like so:
def stringParse ( exp: String, pos: Int, expreshHolder: ArrayBuffer[String], follow: Int ) ={....}
It changes it to "Any". I am confused on how this works. Any ideas? Much appreciated.
Here's a more general answer on how one may approach such problems:
It happens sometimes that you write a function and in your head assume it returns type X, but somewhere down the road the compiler disagrees. This almost always happens when the function has just been written, so while the compiler doesn't give you the actual source (it points to the line where your function is called instead) you normally know that your function's return type is the problem.
If you do not see the type problem straight away, there is the simple trick to explicitly type your function. For example, if you thought your function should have returned Int, but somehow the compiler says it found a Unit, it helps to add : Int to your function. This way, you help the compiler to help you, as it will spot the exact place, where a path in your function returns a non-Int value, which is the actual problem you were looking for in the first place.
You have to add the equals sign if you want to return a value. Now, the reason that your function's return value is Any is that you have 2 control paths, each returning a value of a different type - 1 is when the if's condition is met (and the return value will be temp) and the other is when if's condition isn't (and the return value will be b=b+1, or b after it's incremented).
class Test(condition: Boolean) {
def mixed = condition match {
case true => "Hi"
case false => 100
}
def same = condition match {
case true => List(1,2,3)
case false => List(4,5,6)
}
case class Foo(x: Int)
case class Bar(x: Int)
def parent = condition match {
case true => Foo(1)
case false => Bar(1)
}
}
val test = new Test(true)
test.mixed // type: Any
test.same // type List[Int]
test.parent // type is Product, the case class super type
The compiler will do its best to apply the most specific type it can based on the possible set of result types returned from the conditional (match, if/else, fold, etc.).
"Write a function lv: cfg -> (blabel -> ide set), which computes the live variables analysis on the given control flow graph."
Having cfg and blabel defined and ide set as a list of string, how can I create a function with that signature?
You're presumably familiar with the let syntax to define a function:
let f x = x + 1 in …
You can use this syntax anywhere, including in a function body. Now if you happen to use the inner function's name as the return value of the outer function, the outer function will be returning a function.
let outer_function x =
let inner_function y = x + y in
inner_function
The let syntax is in fact syntactic sugar for fun or function. In particular, if you define inner_function just to use the name once, you might as well use the fun notation and not bother giving the inner function a name.
let outer_function x =
fun y -> x + y
Furthermore, if all the outer function does when you pass it an argument is to build and return an inner function, then consider its behavior when you pass that function two arguments. First the outer function builds an inner function, using its first (and only) argument; then that inner function is applied to the second argument, so its body is executed. This is equivalent to having just one function that takes two arguments. This
observation is known as currying.
let outer_function x y = x + y
Note that the type of this function is int -> int -> int; this is the same type as int -> (int -> int) (the arrow type operator is right-associative).
Currying doesn't apply when the outer function does some work before building the inner function. In that case, the work is performed after receiving the first argument.
let outer_function x =
print_endline "outer";
fun y -> print_endline "inner"; x + y
So the structure of your code is likely to look like this:
let lv (c : cfg) : blabel -> ide set =
let c' = do_some_precomputation c in
fun (bl : blabel) -> (… : ide set)