It is my first day of learning F#. I am going through tryfsharp.org when I came across following example for topic Functions as Values
let chrisTest test =
test "Chris"
let isMe x =
if x = "Chris" then
"it is Chris!"
else
"it's someone else"
chrisTest isMe
Explanation on the site:-
chrisTest is a simple higher order function that executes a test against a string value. The isMe function checks to see if a string is equal to "Chris". Passing isChris to chrisTest passes the string "Chris" as an argument to the `isChris" function, and returns the result of "it is Chris!".
My thought:- Value of isMe function is passed to function chrisTest in the last line of program. However what I do not get is there is no value passed to isMe function. How does isMe function decide to execute what value to return?
For this case we can start by replacing everything in christest. Then you have
chrisTest isMe = isme "Chris" (as test=isme)
and then the rest follows by a similar procedure
Why don't you feed it into F# interactive so you can look at the types as you go:
let chrisTest test = test "Chris";;
val chrisTest : test:(string -> 'a) -> 'a
Here we have a function which we can supply another function as an argument (called test) from string -> 'a, it will call this supplied function with the argument "Chris", returning some result 'a.
let isMe x =
if x = "Chris" then
"it is Chris!"
else
"it's someone else";;
val isMe : x:string -> string
Here we have our simple name-checking function.
Notice that this isMe function is suitable to be supplied as an argument to the christTest function. Notice also that if the argument we supply chrisTest with is of type string -> string, we are going to get a string result. Hopefully you can see here how you can use the type signatures to help you reason about the behaviour of your program.
So, when we supply isMe as an argument to chrisTest, the chrisTest function runs the isMe function with the argument "Chris", returning the result "it is Chris!".
Related
https://tryfsharp.fsbolero.io/
printfn "Hello"
works as expected without errors, however, using pipe operator
"Hello" |> printfn
The type 'string' is not compatible with the type 'Printf.TextWriterFormat'
I understood the pipe operator behavior:
f(a) is equivalent to a |> f
Why does the latter generate the error?? Thanks.
Yes. The pipe operator does what you think it does. However, printfn is "special" that it takes a kind of "formattable string" (there are different kinds of these) and the compiler does its magic only when the format string appears as a direct argument.
In other words, your "Hello" in the first example is not really a string, it is a Printf.TextWriterFormat object, magically created by the compiler.
Still, you can do what you want by using an explict format string. This approach you'll see quite a bit in real-world code:
"Hello" |> printfn "%s"
Here, %s means: give me a string. The magic of F# in this case again takes the format string, here "%s", this time with an argument of type string, and turns it into a function.
Note 1: that this "surprise effect" is being considered and the community works towards adding a printn function (i.e., without the f which stands for format) to just take a simple string: https://github.com/fsharp/fslang-suggestions/issues/1092
Note 2: if you do want to pass arguments to printfn around, you can make the type explicit, but this is done very rarely:
let x = Printf.TextWriterFormat<unit> "Hello"
x |> printfn // now it's legal
Note 3: you might wonder why the compiler doesn't apply its magic to the lh-side of |> as well. The reason is that |> is not an intrinsic to the compiler, but just another overridable operator. Fixing this is therefor technically very hard (there can be any amount of operators on the lh-side), though it has been considered at certain times.
Other alternative
In the comments, the OP suggested that he/she/they didn't like the idea of having to use printfn "%i" and the like, and ended up writing print, printInt etc functions.
If you go that route, you can write your code in a class with only static methods, while using function-style naming. Then just open the static type (this is a new feature in F# 6).
module MyPrinters =
// create a static type (no constructors)
type Printers =
static member print x = printfn "%s" x // string
static member print x = printfn "%i" x // integer
static member print x = printfn "%M" x // decimal
static member print x = printfn "%f" x // float
module X =
// open the static type
open type MyPrinters.Printers
let f() = print 42
let g() = print "test"
I'd expect this code to work. But instead I get this TypeError.
The idea is that myFunctions holds handlers for data received from JSON.
The JSON objects are either of type A, or of type B. If type is "a" I want param to be handled by the function stored in myFunctions.
This is my approach, but the signature of the retrieved function is never allthough all type information is available.
const myFunctions = {
"a": function(o: string) {return "A"},
"b": function(o: number) {return "B"}
};
interface A {
type: "a"
param: string
}
interface B {
type: "b"
param: number
}
function getIt(i: A | B) {
const p = i.param;
const f = myFunctions[i.type];
// at this point typescript identifies the type of f to be ((o: string) => string) | ((o: number) => string)
return f(p); // <- Argument of type 'string | number' is not assignable to parameter of type 'never'. Type 'string' is not assignable to type 'never'.ts(2345)
}
Can someone explain to me why this behaviour occurs and how to fix it?
Alternatively I'd be happy to hear about other approaches to call the correct handler given a certain JSON object.
It is not possible to do this without introducing new if or switch statements. Typescript can't really follow that f and p are related and consistent with one another. Your use case could probably be helped by something like this proposal but that has been sitting as a proposal for a while so I would not really wait for it.
The issue here is that i.type is "A" | "B", so when using it to index myFunctions you just get back a union of all functions (((o: string) => string) | ((o: number) => string)). But this union of functions is only callable with an argument that is an intersection of all possible arguments. That intersection here is string & number which typescript reduces to never since it is a primitive intersection that can never be inhabited by any value. You can read here about the rules on union invocation.
You can add an if or switch to fix this, although it does make the code redundant:
function getIt(i: A | B) {
switch (i.type) {
case "a": return myFunctions[i.type](i.param)
case "b": return myFunctions[i.type](i.param)
}
}
Playground Link
Or use a type assertion to just make things work:
function getIt(i: A | B) {
const p = i.param;
const f = myFunctions[i.type];
return f(p as never);
}
Playground Link
So, i'am learning OCaml step by step and i've recently met the great world of "module langage" in OCaml.
Here is my problem:
module type TEST = sig
val addend : 'a -> list
end
module Test : TEST =
struct
let addend (val,lol) =
val::lol
end
when i try to use this inside the interpretor it tells me that i have a syntax error ...
I know that's this kind of anoying question asked by this guy who's a noob and thinks stack overflow is here to rewrite is poorly optimised code but still, after hours spend searching for a solution i've almost gived up at this point...
OCaml is cool, but why is it so hard.
First, in the definition of the type of your module : you have to specify the type of element of your list. You cannot use list alone.
The following code will compile :
module type TEST = sig
val addend : 'a -> 'a list
end;;
But will not do what you want as you want to define later a function that takes a element, a list and puts this element in this list.
So the signature of such function is :
'a -> 'a list -> 'a list
So the type of your module shall be :
module type TEST = sig
val addend : 'a -> 'a list -> 'a list
end;;
And the implementation :
module Test : TEST =
struct
let addend a l = a::l
end
;;
Please note that in your code, you may be influenced by C like language where you pass the arguments in parenthesis. In Ocaml, parenthesis are used for tuples ; this means that your implementation was different from the signature.
You get a syntax error becaue val is a keyword. You cannot use it as an identifier.
Is it possible to take an FSharp function and convert it to a Dynamic function, alternatively is something like this coming to FSharp in the future?
let func (a:int) (b:int) : int =
a + b
let dynamicFunc = FSharpFunc.ToDynamicFunc(func)
let argumentList = [1; 2]
let object = dynamicFunc argumentList
let result = object :?> int
It appears that you currently have to fall back to standard reflection (like this: calling a F# function by name) however, this approach seems very brittle. Mainly because there's no real guarantee it works, and you have to know what's going on under the covers.
Something like this could be used to wrap any function and do things dynamically.
let wrapFun (x:'f) : 'f =
let args = FSharp.Reflection.FSharpType.GetFunctionElements <| x.GetType()
let runner (any:obj list) : obj =
// Do extra things
FSharpFunc.DynamicInvoke x
FSharp.Reflection.FSharpValue.MakeFunction (typeof<'f>, runner) :?> 'f
F# does support the dynamic call operator. But you must implement yours. Here is a sample Implementation taken from http://www.fssnip.net/2U/title/Dynamic-operator-using-Dynamic-Language-Runtime
// Reference C# implementation of dynamic operations
#r "Microsoft.CSharp.dll"
open System
open System.Runtime.CompilerServices
open Microsoft.CSharp.RuntimeBinder
// Simple implementation of ? operator that works for instance
// method calls that take a single argument and return some result
let (?) (inst:obj) name (arg:'T) : 'R =
// TODO: For efficient implementation, consider caching of call sites
// Create dynamic call site for converting result to type 'R
let convertSite =
CallSite<Func<CallSite, Object, 'R>>.Create
(Binder.Convert(CSharpBinderFlags.None, typeof<'R>, null))
// Create call site for performing call to method with the given
// name and a single parameter of type 'T
let callSite =
CallSite<Func<CallSite, Object, 'T, Object>>.Create
(Binder.InvokeMember
( CSharpBinderFlags.None, name, null, null,
[| CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null);
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) |]))
// Run the method call using second call site and then
// convert the result to the specified type using first call site
convertSite.Target.Invoke
(convertSite, callSite.Target.Invoke(callSite, inst, arg))
You'd be able to use it as follows
// Dynamically invoke 'Next' method of 'Random' type
let o = box (new Random())
let a : int = o?Next(10)
As for the params you'd have to pass them as a Tuple something like
target?method(param1, param2) that would mean that the target method processes its argument as a Tuple and as such, some pattern matching may or may not be involved
Swift programming book says,
By returning a tuple with two distinct values, each of a different
type, the function provides more useful information about its outcome
than if it could only return a single value of a single type.
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/gb/jEUH0.l
I searched on internet but couldn't find any examples of it.So I tried myself like example below, but if you've got better please let me know.. Thanks in advance.
var statusCode = 404
var statusMessage = "No Site"
let http404 = ( sCode : statusCode , sMessage : statusMessage)
func responseFromWS (foo : Int, bar : String) -> (param1 : Int, param2 : String)
{
statusCode = foo
statusMessage = bar
let httpProtocol = ( statusCode , statusMessage)
return httpProtocol
}
responseFromWS(500, "Internal Server Error")
In other languages (including objective c) you can return one value only (of any type), but in some cases you might need to return more than one value.
The pattern usually applied in those cases is to pass references to variables to the function for all additional return values - a typical case is a reference to a NSError * variable, which the function either sets to nil if no error occurs, or to an instance of NSError in case of error.
Such problem is elegantly solved in swift using multiple return values packed in a tuple.
The way you are using this features seems correct, but what's wrong is defining the statusCode and statusMessage variables outside the function scope:
func responseFromWS (foo : Int, bar : String) -> (code: Int, message: String)
{
let statusCode: Int = foo
let statusMessage: String = bar
return (code: statusCode, message: statusMessage)
// Note: you can also write as follows, because the parameter names are defined in the function signature
// return (statusCode, statusMessage)
}
You can use the return value in different ways. As a tuple:
let response = responseFromWS(500, "Internal Server Error")
// Using named parameters
println(response.code) // Prints 500
println(response.message) // Prints "Internal Server Error"
// using parameters by index
println(response.0) // Prints 500
println(response.1) // Prints "Internal Server Error"
As individual variables:
let (code, message) = responseFromWS(500, "Internal Server Error")
println(code)
println(message)
As a subset of individual variables (if you need only a subset of the returned values):
// Assign message only, discard code
let (_, message) = responseFromWS(500, "Internal Server Error")
println(message)
In addition to the uses mentioned by #Antonio, I have used them to return "pseudo-structs" where a function calculates several values, but the definition of a new struct type would really not be used anywhere else.
An example: when calculating true bearing and distance on the surface of the earth, one may choose to return some kind of polar coordinate struct, but the reverse azimuth (not a trivial relation in true geodesy) is also calculated as a by product. In implementations in other languages I have done this by defining a struct type to return the three doubles - but this struct type is never used except to call this function! Better to say
let (distance, azimuth, reverseAzimuth) = coordinate(vectorTo: otherCoordinate)
than having your future self look up the definition of and then unpack some obscure struct.