'No type class instance was found' on multi-parameter type class - typeclass

Is it reasonable to have multi parameter type classes in PureScript?
The compiler raises an unreasonable 'No type class instance was found' error (see full output) for the below type class definition:
class Transform model turn where
transform :: turn -> model -> model
delay :: Maybe turn -> Int
The error arises from the definition of the delay function which doesn't depend on the model type parameter. As evident from the compiler output linked above it substitutes a t0 for the absent model.
What is the proper way to fix this? Currently I workaround this issue by changing the kind of turn as below:
class Turnable model turn where
runTurn :: turn model -> model -> model
turnDelay :: Maybe (turn model) -> Int

rightfold from the FP slack channel gave this answer:
add fundep | turn -> model
Then the instance is looked up only through turn
Consequently I changed the type class definition to this:
class Turnable model turn | turn -> model where
runTurn :: turn -> model -> model
turnDelay :: Maybe turn -> Int
This made the compiler happy. For details, consult Functional dependencies (fundep) in the Haskell wiki and the 24 days of PureScript post.

...in the old days we had used a Proxy (https://github.com/purescript/purescript-proxy) to help the compiler decide which instance to choose.
e.g. :
turnDelay :: Proxy model -> turn -> Int
turnDelay _ turn = .....
and call it by passing in a proxy:
turnDelay (Proxy :: Proxy FooModel) barTurn
I agree FunDeps are the right way to go.

Related

How should i match the Elmish toNavigable argument types

I'm trying to learn the SAFE Stack at the moment, specifically attempting to handle URL navigation via Elmish; I've followed the example code on the Elmish site that defines a route mapping function and then passes that to the parsePath function.
However, Program.toNavigable expects a Parser<'a> type (a type alias for Location -> 'a) as its first argument, but the sample code (parsePath routes) first argument is a Location -> 'a option.
Obviously i can use function composition to get the correct typing, but it seems like I'm missing something here. Can anyone familiar with URL navigation in Elmish advise?
Well, a Parser<'a option> is a Parser<'a> (just with another 'a), so things should compose just fine.
Say, e.g., that the following type defines all navigation:
type Route = Blog of int | Search of string
Then the parties involved should have the following types:
init: Route option -> Model * Cmd<Msg>
parser: Parser<Route option>
urlUpdate: Route option -> Model -> Model * Cmd<Msg>
and you compose your program thusly:
Program.mkProgram init update view
|> Program.toNavigable parser urlUpdate
|> Program.withReactBatched "elmish-app"
|> Program.run

How to call a module dynamically in Erlang?

Assume I have two modules a.erl and b.erl. Both modules contains the same functions ( in Java I would say "both classes implement the same interface" ).
In module "c.erl" I want to have a function that will return module "a" or "b" ( depends on the parameter )
Here is what I want to have in module c.erl
-module(c)
get_handler(Id) ->
% if Id == "a" return a
% if Id == "b" return b
test() ->
get_handler("a"):some_function1("here were go for a"),
get_handler("a"):some_function2("aaaa"),
get_handler("b"):some_function1("here we go for b")
How can I make this work? I am relatively new to Erlang and don't know how to do it. In Java it would be very obvious, because you just return new instance of the class.
Just have get_handler/1 return the module name as an atom, and then use it to call the desired function:
(get_handler("a")):some_function2("aaaa"),
(get_handler("b")):some_function1("here we go for b").
Note that you need parentheses around the call to get_handler/1 in this case.
A simple version of get_handler/1 for modules a and b could be:
get_handler("a") -> a;
get_handler("b") -> b.
If you have an atom in a variable you can use it as a module name.
So, you could define c:get_handler/1 like this:
get_handler("a") -> a;
get_handler("b") -> b.
Your c:test/0 looks ok, except you need extra brackets, like this:
test() ->
(get_handler("a")):some_function1("here were go for a"),
(get_handler("a")):some_function2("aaaa"),
(get_handler("b")):some_function1("here we go for b").
Then in modules a and b just define a some_function1/1 and some_function/2, for example:
some_function1(Str) ->
io:format("module ~s function some_function1 string ~s~n", [?MODULE, Str]).
some_function2(Str) ->
io:format("module ~s function some_function2 string ~s~n", [?MODULE, Str]).
Edit: You should possibly also define a behaviour if you're going to do this sort of thing BTW, which would mean you would declare in modules a and b something like this:
-behaviour(some_behaviour).
Then create module some_behaviour something like this:
-module(some_behaviour).
-callback some_function1 (String :: string()) -> ok .
-callback some_function2 (String :: string()) -> ok .
This means any module like a and b that declare that they support the behaviour some_behaviour must define those functions, and the compiler will speak up if they don't. The types of the parameters and return value are also defined here for static analysis, etc.

Simulating higher-kinded polymorphism with Object Algebra's in F#

In the paper Streams à la carte: Extensible Pipelines with
Object Algebras Biboudis et al. outline a method of "emulating type-constructor ploymorphism" using object algebras.
I am trying to use this method to implement a higher-order example, similar to those described in Typed Tagless Final Interpreters, within F# and have the following:
type App<'f,'a> = interface end
type ExprSYM<'f,'a> =
abstract litInt: int -> App<'f,int>
abstract litBool : bool -> App<'f,bool>
abstract add : App<'f,int> -> App<'f,int> -> App<'f,int>
abstract gt : App<'f,int> -> App<'f,int> -> App<'f,bool>
abstract conj : App<'f,bool> -> App<'f,bool> -> App<'f,bool>
The section relating to Brand Freshness describes nesting a class inside a type constructor. My translation to F# looks like:
type Eval<'a> =
static member t = new obj()
static member prj (app : App<Eval.t,'a>) = app :> Eval<'a>
inherit App<Eval.t,'a>
However, I get the error The type 't' is not defined.
What is the correct way to write this in F#?
Using a nested class doesn't particularly buy you anything; as the authors say
In the Yallop and White technique for OCaml, this is ensured syntactically by the “freshness” of the brand, t, which is private to the type constructor. In Java, the property is ensured by convention: every subtype S of App has a locally defined brand t and no subtype of App<S.t, X> other than S exists.
so you can obtain the same result with a different convention in F# (which doesn't support nested classes or static members within interfaces). For example, you could create the subclass plus a separate marker class inside a module:
module Pull =
type t = class end
type Pull<'t> =
inherit App<t, 't>
let prj (app : App<t, 't>) = app :?> Pull<'t>
and then ensure that you don't use Pull.t elsewhere.

Is there a way to inject support for the F# Option type into ServiceStack?

Updated below...
I recently started experimenting with ServiceStack in F#, so naturally I started with porting the Hello World sample:
open ServiceStack.ServiceHost
open ServiceStack.ServiceInterface
open ServiceStack.WebHost.Endpoints
[<CLIMutable; Route("/hello"); Route("/hello/{Name}")>]
type Hello = { Name : string }
[<CLIMutable>]
type HelloResponse = { Result : string }
type HelloService() =
inherit Service()
member x.Any(req:Hello) =
box { Result = sprintf "Hello, %s!" req.Name }
type HelloAppHost() =
inherit AppHostBase("Hello Web Services", typeof<HelloService>.Assembly)
override x.Configure container = ()
type Global() =
inherit System.Web.HttpApplication()
member x.Application_Start() =
let appHost = new HelloAppHost()
appHost.Init()
That works great. It's very concise, easy to work with, I love it. However, I noticed that the routes defined in the sample allow for the Name parameter to not be included. Of course, Hello, ! looks kind of lame as output. I could use String.IsNullOrEmpty, but it is idiomatic in F# to be explicit about things that are optional by using the Option type. So I modified my Hello type accordingly to see what would happen:
[<CLIMutable; Route("/hello"); Route("/hello/{Name}")>]
type Hello = { Name : string option }
As soon as I did this, the F# type system forced me to deal with the fact that Name might not have a value, so I changed HelloService to this to get everything to compile:
type HelloService() =
inherit Service()
member x.Any(req:Hello) =
box { Result =
match req.Name with
| Some name -> sprintf "Hello, %s!" name
| None -> "Hello!" }
This compiles, and runs perfectly when I don't supply a Name parameter. However, when I do supply a name...
KeyValueDataContractDeserializer: Error converting to type: Type
definitions should start with a '{', expecting serialized type
'FSharpOption`1', got string starting with: World
This wasn't a complete surprise of course, but it brings me to my question:
It would be trivial for me to write a function that can wrap an instance of type T into an instance of type FSharpOption<T>. Are there any hooks in ServiceStack that would let me provide such a function for use during deserialization? I looked, but I couldn't find any, and I'm hoping I was just looking in the wrong place.
This is more important for F# use than it might seem at first, because classes defined in F# are by default not allowed to be null. So the only (satisfying, non-hacky) way of having one class as an optional property of another class is with, you guessed it, the Option type.
Update:
I was able to sort-of get this working by making the following changes:
In the ServiceStack source, I made this type public:
ServiceStack.Text.Common.ParseFactoryDelegate
...and I also made this field public:
ServiceStack.Text.Jsv.JsvReader.ParseFnCache
With those two things public, I was able to write this code in F# to modify the ParseFnCache dictionary. I had to run this code prior to creating an instance of my AppHost - it didn't work if I ran it inside the AppHost's Configure method.
JsvReader.ParseFnCache.[typeof<Option<string>>] <-
ParseFactoryDelegate(fun () ->
ParseStringDelegate(fun s -> (if String.IsNullOrEmpty s then None else Some s) |> box))
This works for my original test case, but aside from the fact that I had to make brittle changes to the internals of ServiceStack, it sucks because I have to do it once for each type I want to be able to wrap in an Option<T>.
What would be better is if I could do this in a generic way. In C# terms, it would be awesome if I could provide to ServiceStack a Func<T, Option<T>> and ServiceStack would, when deserializing a property whose generic type definition matches that of the return type of my function, deserialize T and then pass the result into my function.
Something like that would be amazingly convenient, but I could live with the once-per-wrapped-type approach if it were actually part of ServiceStack and not my ugly hack that probably breaks something somewhere else.
So there are a couple of extensibility points in ServiceStack, on the framework level you can add your own Custom Request Binder this allows you to provide your own model binder that's used, e.g:
base.RequestBinders.Add(typeof(Hello), httpReq => {
var requestDto = ...;
return requestDto;
});
But then you would need to handle the model binding for the different Content-Types yourself, see CreateContentTypeRequest for how ServiceStack does it.
Then there are hooks at the JSON Serializer level, e.g:
JsConfig<Hello>.OnDeserializedFn = dto => newDto;
This lets you modify the instance of the type returned, but it still needs to be the same type but it looks like the F# option modifier changes the structural definition of the type?
But I'm open to adding any hooks that would make ServiceStack more palatable for F#.
What does the code look like to generically convert a normal Hello type to an F# Hello type with option?
The only thing I can think of is to replace the option type with your own type, one that has an implicit conversion from string to myOption, and anything else you need.
Not all that nice, but workable. Your type would probably also need to be serializable.
type myOption =
| None
| Some of string
static member public op_Implicit (s:string) = if s <> null then Some s else None
member public this.Value = match this with
| Some s -> s
| _ -> null
member this.Opt = match this with
| Some s -> Option.Some s
| None -> Option.None
Your record type would then be
[<CLIMutable>]
type Hello =
{ Name : myOption }
On the other hand, ServiceStack is open source, so maybe something could be done there.

Is None less evil than null?

In F# its a big deal that they do not have null values and do not want to support it. Still the programmer has to make cases for None similar to C# programmers having to check != null.
Is None really less evil than null?
The problem with null is that you have the possibility to use it almost everywhere, i.e. introduce invalid states where this is neither intended nor makes sense.
Having an 'a option is always an explicit thing. You state that an operation can either produce Some meaningful value or None, which the compiler can enforce to be checked and processed correctly.
By discouraging null in favor of an 'a option-type, you basically have the guarantee that any value in your program is somehow meaningful. If some code is designed to work with these values, you cannot simply pass invalid ones, and if there is a function of option-type, you will have to cover all possibilities.
Of course it is less evil!
If you don't check against None, then it most cases you'll have a type error in your application, meaning that it won't compile, therefore it cannot crash with a NullReferenceException (since None translates to null).
For example:
let myObject : option<_> = getObjectToUse() // you get a Some<'T>, added explicit typing for clarity
match myObject with
| Some o -> o.DoSomething()
| None -> ... // you have to explicitly handle this case
It is still possible to achieve C#-like behavior, but it is less intuitive, as you have to explicitly say "ignore that this can be None":
let o = myObject.Value // throws NullReferenceException if myObject = None
In C#, you're not forced to consider the case of your variable being null, so it is possible that you simply forget to make a check. Same example as above:
var myObject = GetObjectToUse(); // you get back a nullable type
myObject.DoSomething() // no type error, but a runtime error
Edit: Stephen Swensen is absolutely right, my example code had some flaws, was writing it in a hurry. Fixed. Thank you!
Let's say I show you a function definition like this:
val getPersonByName : (name : string) -> Person
What do you think happens when you pass in a name of a person who doesn't exist in the data store?
Does the function throw a NotFound exception?
Does it return null?
Does it create the person if they don't exist?
Short of reading the code (if you have access to it), reading the documentation (if someone was kindly enough to write it), or just calling the function, you have no way of knowing. And that's basically the problem with null values: they look and act just like non-null values, at least until runtime.
Now let's say you have a function with this signature instead:
val getPersonByName : (name : string) -> option<Person>
This definition makes it very explicit what happens: you'll either get a person back or you won't, and this sort of information is communicated in the function's data type. Usually, you have a better guarantee of handling both cases of a option type than a potentially null value.
I'd say option types are much more benevolent than nulls.
In F# its a big deal that they do not have null values and do not want to support it. Still the programmer has to make cases for None similar to C# programmers having to check != null.
Is None really less evil than null?
Whereas null introduces potential sources of run-time error (NullRefereceException) every time you dereference an object in C#, None forces you to make the sources of run-time error explicit in F#.
For example, invoking GetHashCode on a given object causes C# to silently inject a source of run-time error:
class Foo {
int m;
Foo(int n) { m=n; }
int Hash() { return m; }
static int hash(Foo o) { return o.Hash(); }
};
In contrast, the equivalent code in F# is expected to be null free:
type Foo =
{ m: int }
member foo.Hash() = foo.m
let hash (o: Foo) = o.Hash()
If you really wanted an optional value in F# then you would use the option type and you must handle it explicitly or the compiler will give a warning or error:
let maybeHash (o: Foo option) =
match o with
| None -> 0
| Some o -> o.Hash()
You can still get NullReferenceException in F# by circumventing the type system (which is required for interop):
> hash (box null |> unbox);;
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions.UnboxGeneric[T](Object source)
at <StartupCode$FSI_0021>.$FSI_0021.main#()
Stopped due to error

Resources