Is there a possibility of writing functions which are generic in respect to collection types they support other than using the seq module?
The goal is, not having to resort to copy and paste when adding new collection functions.
Generic programming with collections can be handled the same way generic programming is done in general: Using generics.
let f (map_fun : ('T1 -> 'T2) -> 'T1s -> 'T2s) (iter_fun : ('T2 -> unit) -> 'T2s -> unit) (ts : 'T1s) (g : 'T1 -> 'T2) (h : 'T2 -> unit)=
ts
|> map_fun g
|> iter_fun h
type A =
static member F(ts, g, h) = f (Array.map) (Array.iter) ts g h
static member F(ts, g, h) = f (List.map) (List.iter) ts g h
A bit ugly and verbose, but it's possible. I'm using a class and static members to take advantage of overloading. In your code, you can just use A.F and the correct specialization will be called.
For a prettier solution, see https://stackoverflow.com/questions/979084/what-features-would-you-add-remove-or-change-in-f/987569#987569 Although this feature is enabled only for the core library, it should not be a problem to modify the compiler to allow it in your code. That's possible because the source code of the compiler is open.
The seq<'T> type is the primary way of writing computations that work for any collections in F#. There are a few ways you can work with the type:
You can use functions from the Seq module (such as Seq.filter, Seq.windowed etc.)
You can use sequence comprehensions (e.g. seq { for x in col -> x * 2 })
You can use the underlying (imperative) IEnumerator<'T> type, which is sometimes needed e.g. if you want to implement your own zipping of collections (this is returned by calling GetEnumerator)
This is relatively simple type and it can be used only for reading data from collections. As the result, you'll always get a value of type seq<'T> which is essentially a lazy sequence.
F# doesn't have any mechanism for transforming collections (e.g. generic function taking collection C to collection C with new values) or any mechanism for creating collections (which is available in Haskell or Scala).
In most of the practical cases, I don't find that a problem - most of the work can be done using seq<'T> and when you need a specialized collection (e.g. array for performance), you typically need a slightly different implementation anyway.
Related
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.
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.
Suppose the following module:
module type A = sig
type a
type f = r:a -> unit Lwt.t
end
module type AA = A with type a = B.t
Couldn't I make module A parametrized (turn it into a functor) that accepts B.t as a parameter?
module type A (b: B.t) = sig
type f = r:b -> unit Lwt.t
end
module type AA = A(B.t)
Are these equivalents? Why there's 2 ways of doing the same thing?
Are these equivalents? Why there's 2 ways of doing the same thing?
There isn't, and they aren't. Your "functor" isn't valid, which you could have easily found out by trying it out yourself.
Functors and module constraints (ie. with type ...) work in different domains. Functors work on implementations and module constraints work on signatures/types. Furthermore, module constraints take an existing signature and adds information to it (the constraint), while functors take a module implementation as a parameter, but does not extend it, or need the input and output signatures to have any relationship at all to each other.
You can use a functor to extend implementations generically, using include as explained before. But as the signature of the argument is static its reusability, and therefore its usefulness, is limited:
module A (B1: B) = struct
include B
let x = 42
end
I saw this example in the Julia language documentation. It uses something called Base. What is this Base?
immutable Squares
count::Int
end
Base.start(::Squares) = 1
Base.next(S::Squares, state) = (state*state, state+1)
Base.done(S::Squares, s) = s > S.count;
Base.eltype(::Type{Squares}) = Int # Note that this is defined for the type
Base.length(S::Squares) = S.count;
Base is a module which defines many of the functions, types and macros used in the Julia language. You can view the files for everything it contains here or call whos(Base) to print a list.
In fact, these functions and types (which include things like sum and Int) are so fundamental to the language that they are included in Julia's top-level scope by default.
This means that we can just use sum instead of Base.sum every time we want to use that particular function. Both names refer to the same thing:
Julia> sum === Base.sum
true
Julia> #which sum # show where the name is defined
Base
So why, you might ask, is it necessary is write things like Base.start instead of simply start?
The point is that start is just a name. We are free to rebind names in the top-level scope to anything we like. For instance start = 0 will rebind the name 'start' to the integer 0 (so that it no longer refers to Base.start).
Concentrating now on the specific example in docs, if we simply wrote start(::Squares) = 1, then we find that we have created a new function with 1 method:
Julia> start
start (generic function with 1 method)
But Julia's iterator interface (invoked using the for loop) requires us to add the new method to Base.start! We haven't done this and so we get an error if we try to iterate:
julia> for i in Squares(7)
println(i)
end
ERROR: MethodError: no method matching start(::Squares)
By updating the Base.start function instead by writing Base.start(::Squares) = 1, the iterator interface can use the method for the Squares type and iteration will work as we expect (as long as Base.done and Base.next are also extended for this type).
I'll grant that for something so fundamental, the explanation is buried a bit far down in the documentation, but http://docs.julialang.org/en/release-0.4/manual/modules/#standard-modules describes this:
There are three important standard modules: Main, Core, and Base.
Base is the standard library (the contents of base/). All modules
implicitly contain using Base, since this is needed in the vast
majority of cases.
using let inline and member constraints I'll be able to make duck typing for known members but what if I would like to define a generic function like so:
let duckwrapper<'a> duck = ...
with the signature 'b -> 'a and where the returned value would be an object that implemented 'a (which would be an interface) and forwarded the calls to duck.
I've done this in C# using Reflection.Emit but I'm wondering if F# reflection, quotations or other constructs would make it easier.
Any suggestions on how to accomplish this?
EDIT
after reading Tims answer I thought I'd give a bit more details
What I was thinking of when I wrote about using quotations to help was something like:
{new IInterface with member x.SayHello() = !!<# %expr #>}
!! being an operator translating the quotation to a function and %expr being the unit of work for the method. I'd be able to translate the expression to a function (I guess) but wouldn't know how to
of course this wouldn't do the trick completely either since IInterface would be 'a which is where I hope F# reflection might have some handy functions so that I could construct a type based on a type object and some function values
EDIT
As an update to Tomas Petricek answer I'll give some code to explain my needs
type SourceRole =
abstract transfer : decimal -> context
and context(sourceAccount:account, destinationAccount) =
let source = sourceAccount
let destination = destinationAccount
member self.transfer amount =
let sourcePlayer =
{new SourceRole with
member this.transfer amount =
use scope = new TransactionScope()
let source = source.decreaseBalance amount
let destination = destination.increaseBalance amount
scope.Complete()
context(source,destination)
}
sourcePlayer.transfer(amount)
which is a try at porting "the" textbook example of DCI in F#. The source and destination are DCI roles. It's the idea that any data object that adhere's to a specific contract can play those. In this case the contract is simple. source needs a memberfunction called decreaseBalance and destination needs a member function called increaseBalance.
I can accomplish that for this specific case with let inline and member constraints.
But I'd like to write a set of functions that given an interface and an object. In this case it could be source (as the object) and
type sourceContract =
abstract decreaseBalance : decimal -> sourceContract
as the type. The result would be an object of type sourceContract that would pipe method calls to a method with the same name on the source object.
F# reflection (Microsoft.FSharp.Reflection) is an F#-friendly wrapper around the plain System.Reflection APIs, so I don't think it would add anything here.
Quotations can't define new types: (you'd need to define a new type to do your interface-based duck typing)
> <# { new IInterface with member x.SayHello = "hello" } #>;;
<# { new IInterface with member x.SayHello = "hello" } #>;;
---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stdin(7,4): error FS0449: Quotations cannot contain object expressions
> <# type Test() = class end #>;;
<# type Test() = class end #>;;
---^^^^
stdin(8,4): error FS0010: Unexpected keyword 'type' in quotation literal
Reflection.Emit is still the way to go with this.
Edit:
I hope F# reflection might have some handy functions so that I could construct a type based on a type object and some function values
I'm afraid it doesn't. Here's the documentation on F# reflection: http://msdn.microsoft.com/en-gb/library/ee353491.aspx
You can compile F# quotations using components from F# PowerPack. So I think you could use quotations to generate and execute code at runtime. If you write a quotation representing a function & compile it you'll get a function value that you could use to implement an interface. Here is a trivial example:
#r "FSharp.PowerPack.Linq.dll"
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Linq.QuotationEvaluation
// Create a part using "Expr." calls explicitly
let expr = Expr.Value(13)
// Create a part using quotation syntax
let expr2 = <# (fun x -> x * %%expr) #>
// Compile & Run
let f = expr2.Compile()()
f 10
You can mix quotation syntax and calls to Expr, which makes it easier to compose code from basic blocks. The compilation is a bit stupid (currently) so the generated code won't be as efficient as usual F# code (but you'll need to measure it in your case).
I'm not quite sure I understand what exactly are you trying to do, so if you can provide more details, I can give more specific answer.