I'm trying to work with the ocaml-inotify package. The relevant parts for this question can be defined as follows
module Inotify : sig
type wd
val int_of_wd : wd -> int
end = struct
type wd = int
let int_of_wd wd = wd
end
This work is taking place in a setuid script, and I want the inotify parts to be handled unprivileged, so I'm forking and then setuid-ing down to an unprivileged user in the child. However, this means that I need to pass the wd entities back to the parent through a pipe, and so need to serialise and deserialise them, requiring a int_to_wd function.
I've tried extending the module as follows:
module Rich_Inotify : sig
include module type of Inotify with type wd := int
val wd_of_int : int -> wd
end = struct
include Inotify
let wd_of_int (wd:int) : wd = wd
end
module Inotify = Rich_Inotify
However, the compiler complains that wd is an int and not a wd. How do I persuade it that these types are the same?
If the Inotify module is really defined with this signature, that is sealed with an abstract type, there is no way you will be able to break its abstraction to re-define it as an int. I mean that your signature (module type of Foo with wd := int) is clever and describes the interface you want, but the implementation Foo does not satisfy it: if the type-checker allowed that, there would be no type abstraction at all.
You should request the ocaml-inotify maintainer to add marshalling primitives (and possibly fork it locally to do that if you need). Instead of exposing the fact that wd = int, he or she could either publish conversion functions to and from int (so that future implementation changes could still implement these functions), or directly to and from string if you're only interested in marshalling and want to expose less internal details.
There is a solution that exposes more internal details that back-and-forth conversions to an abstract type, which is to use private type abbreviations:
sig
type t = private int
val mk : int -> t
end
This signature exposes that the internal representation is int, and allows to cast from t to int explicitly with (foo :> int) or (foo : t :> int) (you know that this is a no-op at runtime), but does not allow the inverse cast, so you are forced to use the mk function which, I assume, will do some kind of range checking to make sure that this is a valid descriptor.
(Some people will probably suggest that, as a workaround, you break the type safety of the language by using an unsafe cast that should not be named. Do not; this is bad advice.)
Related
I am new to Kotlin,
data class RewardDetail(
val name: String
val isActivated: Boolean
val amountInCents: Int?
val Campain: String?
val expirationDate: Long?
)
class Rewards(Array<Reward>)
class Reward(
val name: String
isActive: Boolean
amountInCents: Int
campaignId: String
expirationDate: LocalDateTime
)
val details : List<RewardDetail> = blablabla
val rewards = Rewards(details)
can details cast to rewards successfully?
Also note campaignId and Campain field name are different in RewardDetail and Reward and some fields can be nullable in RewardsDetail
What is the best way to handle situation like this?
Kotlin is strongly-typed. You can never successfully cast one thing into a different class. You can only cast an object into a type that it already satisfies. For example, if you have an Int that is currently only known to the compiler to be a Number, you can cast to Int to tell the compiler that it has an Int, so the compiler will allow you to use the functions that are specific to Int. But nothing but an Int can ever be cast to an Int.
So, unlike weakly typed languages, casting does not convert from one type to another. Casting is only you making a promise to the compiler that an object already is of the other type.
In your example, the only way to get a RewardDetail from a Reward is by writing a function that manually converts each property to the appropriate type.
The Rewards class above is largely redundant. There's no need for a wrapper class around a single Array or List unless you need to do validation of items added to or retrieved from the list. In that case, it would probably make more sense to create a subclass of ArrayList for that purpose, so you could still easily iterate the list and use all the List and Iterable helper functions on it.
Probably about 95% of the time, you should prefer using List over using Array. Arrays should be used only when you need a fixed size collection that is also mutable, or if you are working with highly performance-critical code. The reason it should be limited to these uses is that mutability should be avoided when possible for robustness and Arrays are more cumbersome to work with than MutableLists.
A typical implementation of a function that converts from one type to another would be to write an extension function RewardDetail.toReward() extension function, or a toReward() function inside the RewardDetail class. However, in your case you need to decide what you need to happen when some of the values of RewardDetail are null. Maybe you just return null so your conversion function should be toRewardOrNull(), or you provide default values for the properties that have no value in RewardDetail.
EDIT to provide more details:
1) The code that provides the libraries cannot be (easily) changed so profile_v1_type and profile_v2_type should be assumed to be immutable.
I have implemented #francescalus suggestion and it works for my small test case, but I was insufficiently clear about the problem, I think. The reason being that I can only modify my code not the code/types coming from the library. The problem will be that both will have t in the profile_type that gets imported which clash with the parent type.
But I am going to implement something where I replicate the contents of the derived type that I want and then use pointers and type-bound procedures to point to the components of the profile_type version that I want to use. It's not as clean as I wanted it to be but it's much better than I have now.
I am supporting a code that interfaces with another that has 2 versions - the two versions are very similar in interface and although the inputs and outputs are identical in property, they are obviously different derived types (they come from different libraries and differ slightly in the variables contained within. Most variable names inside these types are the same though crucially).
It is (apparently) necessary to support both at runtime, otherwise I would preprocess this all at compile time.
At the moment I have lazily copied and pasted the same code for each version (and all of the versions of derived types it uses) into separate subroutines (*_v1.f90, *_v2.f90).
This is annoying and not very maintainable.
What I'd like to be able to do is use some kind of pointer that doesn't care about what it's pointing to (or rather gets its type information from what it points to and is smart enough to know what's inside).
As I said above, the names are mostly the same, e.g. (t, for temperature, say)
From v1 of library:
TYPE profile_v1_type
REAL :: t
! loads of other stuff
END TYPE profile_v1_type
From v2 of library:
TYPE profile_v2_type
REAL :: t
! loads of other stuff, more than the first version
END TYPE profile_v2_type
In my code:
TYPE profile_container_type
TYPE(profile_v1_type) :: profile_v1
TYPE(profile_v2_type) :: profile_v2
! other arrays that are common inputs to both
END TYPE
! It's actually USE'd then allocated and initialised elsewhere, but I hope you get the idea
!USE profile_container_mod, ONLY : profile_container
TYPE(profile_container_type), TARGET :: profile_container
TYPE(*) :: p
REAL :: t1
!Version determined by a namelist
IF (Version == 1) THEN
p => profile_container % profile_v1
ELSE IF (Version == 2) THEN
p => profile_container % profile_v2
ENDIF
t1 = p % t + 1
.
.
.
ifort 19 gives these (expected) errors:
test.f90(24): error #8776: An assumed type object must be a DUMMY argument. [P]
TYPE(*), POINTER :: p
--------------------^
test.f90(24): error #8772: An assumed type object must not have the ALLOCATABLE, CODIMENSION, POINTER, INTENT(OUT) or VALUE attribute. [P]
TYPE(*), POINTER :: p
--------------------^
test.f90(39): error #6460: This is not a field name that is defined in the encompassing structure. [T]
t1 = p % t + 1
---------^
compilation aborted for test.f90 (code 1)
replace TYPE(*) with CLASS(*) gives the (still expected):
test2.f90(39): error #6460: This is not a field name that is defined in the encompassing structure. [T]
t1 = p % t + 1 ! or some clever function...
---------^
compilation aborted for test2.f90 (code 1)
This is fixed by SELECTing the type that you want to handle, but my point is that I want to do the same thing for either the v1 and v2 code (it will never be both). And I want to do it many times, not in this routine but in about a dozen routines.
I am open to using C pointers if the responder is able to provide a simple example to follow. I have tried (not recently) to solve this problem using C interoperability, but obviously without success!
Unlimited polymorphic entities are not the correct approach here.
Instead, we can define a base type which incorporates all of the common data and processing for the various other types. Here, let's call this base type profile_base_type:
type profile_base_type
real t
end type
The other two specific profiles can extend this base:
type, extends(profile_base_type) :: profile_v1_type
! v1 specific parts
end type
type, extends(profile_base_type) :: profile_v2_type
! v2 specific parts
end type
Then we can declare a polymorphic pointer of the base type
class(profile_base_type), pointer :: p
which can point to targets of either of the extending types:
p => profile_container%profile_v1
p => profile_container%profile_v2
Now, we can access the components of p which are in the type profile_base_type
t1 = p%t + 1
without having to use a select type construct.
Naturally, those specific aspects of the extending types cannot be accessed in this way but there are other considerations for that.
Suppose we have a module that defines an abstract type T:
module AbstractType (T, lexer) where
data T = T String deriving Show
lexer = (fmap T) . words
(Note that we do not export any type constructors for T, so the user would not be able to draft an instance by hand.)
How does one unit test lexer function?
Sure we may use the Show property of T, like this:
module Main where
import AbstractType
main = test
(show $ lexer "summer is miles and miles away")
"[T \"summer\",T \"is\",T \"miles\",T \"and\",T \"miles\",T \"away\"]"
test :: (Eq a) => a -> a -> IO ()
test expression expectation
| expression == expectation = putStrLn "Test passed."
| otherwise = error "Test failed."
— But this is both not beautiful and unfit for cases when our abstract type is not an instance of a class that permits casting to another, constructable type.
Is there a remedy?
P.S. To provide some justification for the case: suppose we have a chain of functions like parser . lexer that we can integration test and see if the whole of it works. As the chain at hand gets more complex, it may nevertheless become desirable to unit test each link individually.
The example is a simplified excerpt from an actual toy text processor I am in the process of writing.
The generally accepted best practice is, for an exposed module A, to create an internal module A.Internal that is either:
Exposed but documented to be unstable or unsafe.
Not exposed to the users of the package, but only to the testing facilities. (This is made possible by the internal libraries feature released in Cabal 2.0.)
It is my understanding that functions that are not exposed enjoy more radical optimizations, particularly inlining. I am not sure if it applies to functions in internal libraries too.
On the other hand, situations often arise when a user desperately needs some internal feature of your library and ends up forking and patching it to gain access. This is, of course, unfortunate and undesirable.
I would say generally that the implementation of an abstract type is best kept in an internal library as a safety measure, but you should use your judgement in each particular case.
I'm reading some Ocaml project's source code and I'm new to Ocaml.I'm confused in the following code,which is a some kind of type definition in a .ml file.
type event = Event.t = ..
What's the meaning of '..' in the code,I searched the manual but get nothing. And in the event.mli,the type definition is :
type t = ..
type event = t = ..
Any help is appreciated,thanks.
Its new "extensible variant types". See http://caml.inria.fr/pub/docs/manual-ocaml/extn.html#sec251 for details.
You can declare a empty extensible variant type with
type t = ..
then later you can add new constructors like
type t += Foo | Bar of int
You can add constructors to extensible variants more than once places of programs. Instead, you cannot enjoy non-exhaustiveness check at pattern match, which is available for normal variants.
type event = t = .. declares an alias event of already existing extensible type t. = .. is required to make the new type also extensible.
type event = t = ..
type event += Poo (* you cannot do this if type event = t *)
Note
Extensible variant types may be useful when:
You do not want to fix the set of the constructors.
You feel constructors are rather loosely related each other and see no benefit to declare them in one place.
For example, the type of various errors of an application is a good candidate to define as an EVT: an app may fail due to a network issue, an auth failure, disk full and so on. They are unrelated with each other and come from many parts of the app. In that case you may want to define the type error as an EVT:
(* module Error *)
type t = ..
(* module Web *)
type Error.t += Http of int (* ex. 404 *)
(* module Tempfile *)
type Error.t += Diskfull of Path.t
(* module ErrorHandler *)
let print_error (e : Error.t) = match e with
| Web.HTTP stat -> ...
| Tempfile.Diskfull path -> ...
| ...
You may notice it looks like exceptions, actually EVT is generalized version of exception.
It is an extensible variant type. It's a variant to which you can add new cases in other places than the definition point. For example you can add to this event yourself in your code by writing:
type event +=
| Mouse_move of int * int
| Mouse_down of int * int
Extensible variant types are part of the language since 4.02 and are described in the manual in this section.
I've heard that "first class modules" are coming in OCaml 3.12. What advantages will they offer? What kids of things will be easier? What problem are they trying to solve? A simple example would suffice.
It's only one possible applications, but first class modules make it easy to encode existential types, with basically a module packing an existential type and a value using this type). For example, See Alain Frisch work on Dynamic types (code taken from Alain Frisch work on dyntypes : http://caml.inria.fr/cgi-bin/viewvc.cgi/ocaml/branches/dyntypes/stdlib/dyntypes.ml?view=markup )
module type DYN = sig
type t
val x: t
val t: t ttype
end
type dyn = (module DYN)
let dyn (type s) t x =
let module M = struct
type t = s
let x = x
let t = t
end
in
(module M : DYN)
The idea here is that "ttype" is a concrete representation of that type, an algebraic datatype with Int, Float constructors and so on, and you have here a value, whose type is concealed, but that carries a concrete representation of that type, that you can use for example to get a safer serialization/deserialization.
Maybe a bit late, but the new paper First-class modules: hidden power and tantalizing promises is exactly on topic. It's a set of recipes/pearls around first-class modules, by Oleg Kiselyov (oleg) and Jeremy Yallop (author, for example, of the Deriving project).