Is the same Empty returned when it matched in a function? - pointers

we have mapOptional from the NICTA course:
mapOptional :: (a -> b) -> Optional a -> Optional b
mapOptional _ Empty = Empty
mapOptional f (Full a) = Full (f a)
When matching f we obviously use that function that was passed, what about the Empty? and what about Full?

There is nothing in Haskell that lets you observe whether the two Emptys are the same Empty or not, and no guarantees about what an implementation must do with that code in that regard.
That said, in GHC, nullary constructors for a given parameterized type are shared across all parameterizations; so there is just one Empty in the whole program, and just one [], and so forth.

They can't be the same Empty, the argument has the type Optional a and the output has the type Optional b. When I try to force some sort of reuse, I will typically use something of the type
mapOptional _ a#Empty = a
This won't compile, and I don't think that's implementation dependent.

Related

SProxy in purescript?

What's the use of Sproxy in purescript?
In Pursuit, it's written as
data SProxy (sym :: Symbol)
--| A value-level proxy for a type-level symbol.
and what is meant by Symbol in purescipt?
First, please note that PureScript now has polykinds since version 0.14 and most functions now use Proxy instead of SProxy. Proxy is basically a generalisation of SProxy.
About Symbols and Strings
PureScript knows value level strings (known as String) and type level strings (known as Symbol).
A String can have any string value at runtime. The compiler does not track the value of the string.
A Symbol is different, it can only have one value (but remember, it is on the type level). The compiler keeps track of this string. This allows the compiler to type check certain expressions.
Symbols in Practice
The most prominent use of Symbols is in records. The difference between a Record and a String-Map is that the compiler knows about the keys at compile time and can typecheck lookups.
Now, sometimes we need to bridge the gap between these two worlds: The type level and the value level world. Maybe you know that PureScript records are implemented as JavaScript objects in the official compiler. This means we need to somehow receive a string value from our symbol. The magical function reflectSymbol allows us to turn a symbol into a string. But a symbol is on the type level. This means we can only write a symbol where we can write types (so for example in type definition after ::). This is where the Proxy hack comes in. The SProxy is a simple value that "stores" the type by applying it.
For example the get function from purescript-records allows us to get a value at a property from a record.
get :: forall proxy r r' l a. IsSymbol l => Cons l a r' r => proxy l -> Record r -> a
If we apply the first paramerter we get:
get (Proxy :: Proxy "x") :: forall r a. { x :: a | r } -> a
Now you could argue that you can get the same function by simply writing:
_.x :: forall r a. { x :: a | r } -> a
It has exactly the same type. This leads to one last question:
But why?
Well, there are certain meta programming szenarios, where you don't programm for a specific symbol, but rather for any symbol. Imagine you want to write a JSON serialiser for any record. You might want to "iterate" over every property of the record, get the value, turn the value itself into JSON and then concatinate the key value pair with all the other keys and values.
An example for such an implementation can be found here
This is maybe not the most technical explanation of it all, but this is how I understand it.

Ocaml - Runtime compilation of code as a string

I want to parse and compile a function that I have written at runtime, for example I have the following string I generated at runtime:
let str = "fun x y z -> [x; y; z;]"
I am looking for something that will allow me to do something similar to:
let myfun = eval str
(* eval returns the value returned by the code in the string so myfun will
have the type: 'a -> 'a -> 'a -> 'a list*)
Is there a way to do that in OCaml? I came across Dynlink but I am looking for a simpler way to do it.
There is no easier solution than compiling the code and Dynlinking the resulting library.
Or equivalently, one can use the REPL, write the string to the file system and them load it with #use.
Depending on your precise use case, MetaOCaml might be an alternative.
Another important point is that types cannot depend on values in a non-dependently typed language. Thus the type of eval needs to be restricted. For instance, in the Dynlinking path, the type of dynamically linked functions will be determined by the type of the hooks used to register them.

Unboxing values of F# discriminated unions

Some functions of my F# code receive values boxed as object even though the underlying values are typed. If the value is a discriminated union, it's not possible to unbox it back to its F# type. Here is a simple example:
type Result<'TOk,'TError> =
| Ok of 'TOk
| Error of 'TError
type ResultA = Result<string, int>
let a = Ok "A"
let o = box a
match o with
| :? ResultA -> printfn "match ResultA"
// | :? ResultA.Ok -> printfn "match" // doesn't compile
| _ when o.GetType().DeclaringType = typedefof<ResultA> -> printfn "match via reflection"
| _ -> printfn "no match"
The output from this example is "match via reflection", ResultA is never matched because the boxed value is of a different CLR type - Result.Ok. Since F# discriminated union cases are represented as its own types, the boxed value doesn't match the type ResultA. Moreover, it's not possible to match it to ResultA.OK because inside F# code it's not a legal type. The only option seems to be manual instantiation of a value using reflection, which is inefficient and silly because the value is already instantiated, it's here, it just can not be accessed in F# code once it's boxed.
Am I overlooking something? Is there a more straightforward way of unboxing an F# discriminated union value?
You're just matching a different type. Your variable a is not of type ResultA, but of generic type Result<string, 'a>, which when boxed gets coerced to Result<string, obj>.
Either make the variable have the right type explicitly:
let a : ResultA = Ok "A"
Or match with the right type:
match o with
| :? Result<string, obj> -> printfn "match ResultA"
Both options will work.
A note on your assumption:
ResultA is never matched because the boxed value is of a different CLR type - Result.Ok
That is not the reason. Matching with a type works just the same as the is/as operators in C# - i.e. it matches subtypes as well as the exact type. And DU members get compiled as subtypes of the DU type itself. That is how F# can get .NET to handle different cases as one type.
A note on runtime typing in general:
Handling types at runtime shouldn't be necessary. Try to avoid it if at all possible. The rule of thumb should be, if you find yourself handling types at runtime, you've probably modeled something wrong.
This is especially true if you don't know exactly how everything works.

How to keep elements in list through out the program in SML?

Suppose I have to update a list with each call to a function, such that, the previous element of the list are preserved.
Here is my attempt:
local
val all_list = [];
in
fun insert (x:int) : string = int2string (list_len( ((all_list#[x])) ) )
end;
The problem is that each time I call to insert, I get the output "1", which indicates that the list is initiated to [] again.
However I was expecting output of "1" for the first call to insert, and "2" for the second call,...etc.
I am not able to come with a workaround. How should it be done?
You need to use side-effects.
Most of the time functional programmers prefer to use pure functions, which don't have side effects. Your implementation is a pure function, so it will always return the same value for the same input (and in your case it returns the same value for any input).
You can deal with that by using a reference.
A crash course on references in Standard ML:
use ref to create a new reference, ref has type 'a -> 'a ref, so it packs an arbitrary value into a reference cell, which you can modify later;
! is for unpacking a reference: (!) : 'a ref -> 'a, in most imperative languages this operation is implicit, but not in SML or OCaml;
(:=) : 'a ref * 'a -> unit is an infix operator used for modifying references, here is how you increment the contents of an integer reference: r := !r + 1.
The above gives us the following code (I prepend xs onto the list, instead of appending them):
local
val rxs = ref []
in
fun insert (x:int) : string =
(rxs := x :: !rxs;
Int.toString (length (!rxs)))
end
Values are immutable in SML. insert is defined in a context in which the value of all_list is [] and nothing about your code changes that value.
all_list#[x]
doesn't mutate the value all_list -- it returns a brand new list, one which your code promptly discards (after taking its length).
Using reference types (one of SML's impure features) it is possible to do what you seem to be trying to do, but the resulting code wouldn't be idiomatic SML. It would break referential transparency (the desirable feature of functional programming languages where a function called with identical inputs yields identical outputs).

How to call two functions and use their results as arguments for each other?

I have code:
let join a ~with':b ~by:key =
let rec a' = link a ~to':b' ~by:key
and b' = link b ~to':a' ~by:(Key.opposite key) in
a'
and compilation result for it is:
Error: This kind of expression is not allowed as right-hand side of
`let rec' build complete
I can rewrite it to:
let join a ~with':b ~by:key =
let rec a'() = link a ~to':(b'()) ~by:key
and b'() = link b ~to':(a'()) ~by:(Key.opposite key) in
a'()
It is compilable variant, but implemented function is infinitely recursive and it is not what I need.
My questions: Why is first implementation invalid? How to call two functions and use their results as arguments for each other?
My compiler version = 4.01.0
The answer to your first question is given in Section 7.3 of the OCaml manual. Here's what it says:
Informally, the class of accepted definitions consists of those definitions where the defined names occur only inside function bodies or as argument to a data constructor.
Your names appear as function arguments, which isn't supported.
I suspect the reason is that you can't assign a semantics otherwise. It seems to me the infinite computation that you see is impossible to avoid in general.

Resources