I have this functor that has a submodule:
module type PT = sig
type t
val to_string: t -> string
end
module A(P:PT) = struct
module SubA = struct
type t = T of P.t | F of float
end
end
And I want to extend it using an include. This even works:
module Aplus(P:PT) = struct
include A(P)
let print x = print_string (P.to_string x)
end
But for some reason it doesn't work for submodules.
module Aplus(P:PT) = struct
include A(P)
let print x = print_string (P.to_string x)
module SubAplus = struct
include A(P).SubA (* Syntax error here *)
end
end
It fails with a Syntax error on the submodule reference after a functor application. That is quite strange, since it looks like the language grammar allows that. Is there any specific reason for disallowing that?
OCaml syntax in a module path, allows you only to reference to module types, type constructors and types:
For referring to type constructors, module types, or class types, the
prefix can also contain simple functor applications (as in the
syntactic class extended-module-path above) in case the defining
module is the result of a functor application.
In other words to access to real values, you need to instantiate your module, and then you can reference any values. See Drup's answer for a complete example.
Easy enough:
module M = F(A)
include M.SubModule
There are various possible reason, but one simple is: if the module resulting of the functor application F(A) is not named, you will not be able to refer to it. If the function introduces type equalities in the context, it will lead to issues (and in error messages in particular ...)
Note that it's possible to do it with types, module types and class types. F(M).M.t is a perfectly valid type expression.
To finish, in your case, you don't need to reapply the functor, you already did earlier, so include SubA will be enough.
Related
This is a minor issue but annoying.
module Example : sig
type t = int
end = struct
type t = int
end
I get that I have to include the type in the signature, otherwise it's abstract and hidden... that's fine. But is it necessary to write it out in the struct as well? In this case it's pretty trivial, but if I have a lot of large records or other complex types it gets annoying. I could just not include a sig at all, but I often want some publicly visible types but also some hidden properties.
As far as I can tell, nothing will compile if the struct doesn't exactly copy the type definition from the signature.. is there any way to tell it "Just copy what's in the signature", rather than actually having to copy and paste? If not... why not?
Well yes and no.
You can just write:
module Example =
struct
type t = int
end
This code will work just as you'd expect.
However, and to our common sadness, there is no way to "import" your type definition from the signature. Copy-paste is your friend.
Side-note: As #G4143 mentioned in the comments, you can type ocamlc -i myfile.ml to print a complete type signature of your module, that can be useful too.
I am trying to use FakeItEasy to mock an interface defined in C#
public interface IMyInterface
{
int HeartbeatInterval { get; set; }
}
In the F# test i do
let myFake = A.Fake<IMyInterface>()
A.CallTo(fun () -> ((!myFake).HeartbeatInterval)).Returns(10) |> ignore
Running this in the test runner results in
System.ArgumentException
Expression of type 'Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.Int32]' cannot be used for return type 'System.Int32'
In fact it would seem that it does this for any return type e.g. if HeartbeatInterval returned type of foo then the exception thrown would be for type foo instead of System.Int32.
Am i doing this wrong or is there some incompatibility between F# and FakeItEasy?
It has crossed my mind that using an Object Expression might be an easier way to go.
I would venture a hypothesis that the "Easy" in "FakeItEasy" stands for "Easy Over Simple". The library says it's "easy", and that is probably true if you're using it from C#. Because it is quite obviously designed for use with that language. But it is far from "simple", because it is using C#-specific syntactic tricks that are hidden from view and don't work in F# well.
The specific gotcha you're getting right now is a combination of two things: (1) F# functions are not the same as C# Func<T,R>, and (2) F# overload resolution rules are different from C#.
There are three overloads of CallTo - two of them take an Expression<_>, and the third one is a "catch-all", taking an object. In C#, if you call this method with a lambda-expression as argument, the compiler will try its best to convert the lambda-expression to an Expression<_> and call one of the specialized methods. F#, however, does not make this effort: F#'s support for C#-style Expression<_> is very limited, primarily focused on compatability with LINQ, and only kicks in when there are no alternatives. So in this case, F# chooses to call the CallTo(object) overload.
Next, what would the argument be? F# is a very strict and consistent language. Apart from some special interop cases, most F# expressions have a definite type, regardless of the context in which they appear. Specifically, an expression of the form fun() -> x will have type unit -> 'a, where 'a is the type of x. In other words, it's an F# function.
At runtime, F# functions are represented by the type FSharpFunc<T,R>, so that is what the compiler will pass to the CallTo(object) method, which will look at it and, unable to understand what the hell it is, throw an exception.
To fix it, you could make yourself a special version of CallTo (let's call it FsCallTo) that would force the F# compiler to convert your fun() -> x expression into an Expression<_>, then use that method instead of CallTo:
// WARNING: unverified code. Should work, but I haven't checked.
type A with
// This is how you declare extension methods in F#
static member FsCallTo( e: System.Linq.Expressions.Expression<System.Func<_,_>> ) = A.CallTo( e )
let myFake = A.Fake<IMyInterface>()
// Calling FsCallTo will force F# to generate an `Expression<_>`,
// because that's what the method expects:
A.FsCallTo(fun () -> ((!myFake).HeartbeatInterval)).Returns(10) |> ignore
However, as you have absolutely correctly observed, this is way too much of a hassle for mocking up an interface, since F# already has a perfectly statically verifiable, runtime-cost-free, syntactically nice alternative in the form of object expressions:
let myFake = { new IMyInterface with
member this.HeartbeatInterval = 10
member this.HeartbeatInterval with set _ = ()
}
I would totally recommend going with them instead.
Consider a function foo that takes another function f and data of unknown type d. If neither the return type of f nor the type of d are known at the time of function definition, how might the function declaration be specified? That is, how can I express something like the following:
void foo(_ f, _ d) {
// ..
where _ indicates a wildcard/catch-all match for the type.
Another question by extension: Is it possible to specifying that the types be the same if their identity can be anything? In other words _ might be any type, but the types need to be the same.
Functions have to know their type. It would be pretty hard to generate code for them otherwise, and the linker certainly couldn't deal with them. That being said, like C++, D has templates, so you can declare function templates so that the function itself is generated and compiled when code using it is compiled. So, if you want a function that takes two arguments of the same type but will work with various types, then you'll want to use a function template. e.g.
void foo(T)(T a, T b)
{
...
}
Or if multiple types were needed, you could do something like
void foo(T, U)(T a, U b)
{
...
}
In either case, when code then calls foo, the types of the parameters will be inferred by the compiler from the types of the actual arguments. Calling the same function template with different argument types will result in additional functions being generated by the compiler. The relevant part of the official docs is here:
http://dlang.org/spec/template.html#function-templates
But this chapter from an online book would probably be more informative:
http://ddili.org/ders/d.en/templates.html
I'd suggest that you consider reading the whole book (or at least looking it over) if you want something that explains a lot of the basics of D.
My question is if there is any difference between Standard ML's module system and OCaml module system? Has OCaml all the support of functors , ascriptions etc... that SML has?
There are some differences feature-wise, as well as semantically.
Features SML supports but not OCaml:
transparent signature ascription
module-level let
symmetric sharing constraints
syntactic sugar for functors over types and values
Features OCaml 4 has but not SML:
higher-order functors
recursive modules
local modules
nested signatures
modules as first-class values
general module sharing (sig with module A = M)
module type of
Several SML implementations provide some of these as extensions, however: e.g. higher-order functors (SML/NJ, Moscow ML, Alice ML), local and first-class modules (Moscow ML, Alice ML), module sharing (SML/NJ, Alice ML), nested signatures (Moscow ML, Alice ML), and recursive modules (Moscow ML).
Semantics-wise, the biggest difference is in the treatment of type equivalence, especially with respect to functors:
In SML, functors are generative, which means that applying the same functor twice to the same argument always yields fresh types.
In OCaml, functors are applicative, which means that applying the same functor twice to the exact same argument (plus additional syntactic restrictions) reproduces equivalent types. This semantics is more flexible, but can also break abstraction (see e.g. the examples we give in this paper, Section 8).
Edit: OCaml 4 added the ability to optionally make functors generative.
OCaml has a purely syntactic notion of signatures, which means that certain type equivalences cannot be expressed by the type system, and are silently dropped.
Edit: Consider this example:
module F (X : sig type t end) = struct type u = X.t -> unit type v = X.t end
module M = F (struct type t = int end : sig type t end)
The type of M is simply sig type u type v end and has thus lost any information about the relation between its types u and v, because that cannot generally be expressed in the surface syntax.
Another notable difference is that OCaml's module type system is undecidable (i.e, type checking may not terminate), due to its permission of abstract signatures, which SML does not allow.
As for semantics, a much better and elaborate answer is given by Andreas Rossberg above. However, concerning syntax this site might be what you are looking for.
There is also the abstype facility in SML which is like the datatype facility, except that it hides the structure of the datatype. OCaml relies on module abstraction to do all the hiding that is necessary. Notice that this site does not mention this facility in SML.
If I have a type t
type t = C of string;;
And want to explicitly define a type of the variable to be type t:
let b : t = C 'MyString';;
Can I do it in OCaml?
You don't need to be explicit
let b = C mystring
let b = C "a string litteral"
You can be explicit, but it dy oesn't add anything
let b : t = C foo
The preferred way in general is to use type inference without annotating types, and only be explicit about the type of the identifiers exported to other modules, through the associated .mli interface file.
In this case, a type annotation doesn't add anything as the C constructor already is a kind of tag/annotation : C something is necessarily of type t, there is no possible confusion.
You can, using either that syntax, or the alternate one:
let b = (C foo : t)
Adding type constraints in this fashion does not usually serve any purpose in a well-formed program, because the type inference algorithm can handle all of it correctly on its own. There are a few exceptions (mostly involving the object-oriented side), but they're quite rare.
Such annotations are mostly useful when a type error happens and you need to understand why a certain expression has a certain type when you expected it to have another, because you can type-annotate intermediate values to have the type error move up through your source code.
Note that there's another way of annotating types, which is to define a signature for your modules. In your example above, your module body would contain:
let b = C foo
And your module signature would contain :
val b : t
This is especially useful when you need assumptions inside the module to be invisible to other modules. For instance, when using polymorphic variants:
let user_type = `Admin
Here, you only want to handle the administrator account, but you need the rest of your code to be aware that other account types exist, so you would write in the signature that:
val user_type : [`Admin|`Member|`Guest]
This type is technically correct, but could not have been guessed by the type inference algorithm.