Idris interface syntax - syntax-error

I am trying to compile simple example of interface in Idris.
interface Foo a where
foo : a -> String
But I keep getting this type-checking error:
error: expected: "with",
argument expression,
function right hand side,
implicit function argument,
with pattern
interface Foo a where
^
I believe it should be logically the same as the Show interface in the tutorial: http://docs.idris-lang.org/en/latest/tutorial/interfaces.html Has the syntax changed? Or where could be the problem?
I am using Idris version 0.9.12.

In Idris 0.9.12, the syntax for what is now called interfaces is class:
class Foo a where
foo : a -> String

Related

E2003 undeclared identifier in other unit, delphi [duplicate]

I am constantly getting the: Undeclared identifier for an interface type I have defined in another unit.
Here is what I have:
unit Drawers;
interface
implementation
type
IDrawer = interface
['{070B4742-89C6-4A69-80E2-9441F170F876}']
procedure Draw();
end;
end.
unit Field;
interface
uses
Graphics, Classes, Drawers;
TField = class(TInterfacedObject, IField)
private
FSymbolDrawer: IDrawer;
At FSymbolDrawer I get the complier error.
Of course I have the uses Drawers; in the unit where TField is defined.
What's this about?
Thank you
In the unit Drawers the type declaration of IDrawer has to be in the interface part of the unit. You have inserted it in the implementation part where it is only visible for in-unit declarations.
Here is the code:
unit Drawers;
interface
type
IDrawer = interface
['{070B4742-89C6-4A69-80E2-9441F170F876}']
procedure Draw();
end;
implementation
end.
Which uses clause do you add Drawers to? It has to be in the interface uses clause (above the definition of TField that uses it).

Fortran: class in abstract interface [duplicate]

This question already has answers here:
Why is the type not accessible?
(2 answers)
Closed 6 years ago.
Using cygwin64 on Windows this program won't compile:
program test
implicit none
!define my type
type myType
real::foo
integer::bar
end type myType
!define an operator for this type
interface operator (>)
logical function compare(a,b)
type(myType),intent(in) :: a,b
compare = a%foo>b%foo
end function compare
end interface operator (>)
!simple example of operator usage
type(myType) :: tfoo, tbar
tfoo = card(1.,2); tbar = card(3.,4)
print*, tfoo>tbar
end program test
gfortran (only argument is "std=f2008") tells me:
type(myType),intent(in) :: a,b
1
Error: Derived type ‘mytype’ at (1) is being used before it is defined
which is confusing to me, since the type is defined right before the operator. I'm relatively new to Fortran, so this example code might have some more errors.
The same problem occurred here, but encapsulating myType in a separate module did not resolve the issue.
There are several issues with your code, but this particular error is because myType is in the host scope, but not in the interface block. The solution is to either place the derived type in a separate module as suggested in the linked thread, or import the derived type from the host scoping unit:
interface operator (>)
logical function compare(a,b)
import myType
type(myType),intent(in) :: a,b
end function compare
end interface operator (>)
This is described in the Fortran 2008 Standard, Cl. 12.4.3.3 "IMPORT statement":
1 The IMPORT statement specifies that the named entities from the host scoping unit are accessible in the interface
body by host association. An entity that is imported in this manner and is defined in the host scoping unit shall be
explicitly declared prior to the interface body.
An interface block may not have executable statements included - so the assignment you have there is not valid. Furthermore, card is not defined in your code.

Unexpected tokens (use ';' to separate expressions on the same line) error in Kotlin

I get this error with the below code (last line): Unexpected tokens (use ';' to separate expressions on the same line)
private val myClass: Class<String>
get() = String::class.java
myClass: Class<*> = extras!!.getSerializable("myClass") as Class<Activity?>
How can i fix it?
the reason why IDE show this error is because your variable myClass have two types Class<String> and Class<Activity?>.
I guess what you are trying to do is retrieve an extra from a Bundle and casting into a correct object to use it.
So here is some pseduo codes:
private lateinit var myClass: Class<Activity>
override fun onCreate(savedInstanceState: Bundle?) {
myClass = intent?.extras!!.getSerializable("myClass") as Class<Activity>
}
this way at least there isn't anymore error, however you may need to consider the cast safety since you need to check it.
You are trying to type myClass in an assignment (type annotations in assignments can only be used on the right side of the =).
The compiler assumes that you mean to write a second expression (starting from :), since myClass is already an expression of type Class<String>, and informs you that you should use ; to separate expressions on the same line.
Type annotations for Variables can only be used in declarations.
As a side note: That assignment won't work anyway, since myClass is immutable (keyword val) and the types are incompatible too (Class<Activity?> is not a Class<String>).

'How to use higher order functors properly?' or 'How to have serious fun with funsigs?'

Motivation
For the life of me, I cannot figure out how to use higher order functors in
SML/NJ to any practical end.
According to the
SML/NJ docs on the implementation's special features,
it should be possible to specify one functor as an argument to another by use of
the funsig keyword. Thus, given a signature
signature SIG = sig ... end
we should be able to specify a functor that will produce a module satisfying
SIG, when applied to a structure satisfying some signature SIG'. E.g.,
funsig Fn (S:SIG') = SIG
With Fn declared in this way, we should then (be able to define another
functor that takes this functor as an argument. I.e., we can define a module
that is parameterized over another parameterized module, and presumably use the
latter within the former; thus:
functor Fn' (functor Fn:SIG) =
struct
...
structure S' = Fn (S:SIG')
...
end
It all looks good in theory, but I can't figure out how to actually make use of
this pattern.
Example Problems
Here are two instances where I've tried to use this pattern, only to find
it impracticable:
First attempt
For my first attempt, just playing around, I tried to make a functor that would
take a functor implementing an ordered set, and produce a module for dealing
with sets of integers (not really useful, but it would let you parameterize sets
of a given type over different set implementations). I can define the
following structures, and they will compile (using Standard ML of New Jersey
v110.7):
structure IntOrdKey : ORD_KEY
= struct
type ord_key = int
val compare = Int.compare
end
funsig SET_FN (KEY:ORD_KEY) = ORD_SET
functor IntSetFn (functor SetFn:SET_FN) =
struct
structure Set = SetFn (IntOrdKey)
end
But when I actually try to apply IntSetFn to a functor that should satisfy the
SET_FN funsig, it just doesn't parse:
- structure IntSet = IntSetFn (functor ListSetFn);
= ;
= ;;
stdIn:18.1-24.2 Error: syntax error: deleting RPAREN SEMICOLON SEMICOLON
- structure IntSet = IntSetFn (functor BinarySetFn) ;
= ;
= ;
stdIn:19.1-26.2 Error: syntax error: deleting RPAREN SEMICOLON SEMICOLON
Second attempt
My second attempt fails in two ways.
I have defined a structure of nested modules implementing polymorphic and
monomorphic stacks (the source file, for the curious). To
implement a monomorphic stack, you do
- structure IntStack = Collect.Stack.Mono (type elem = int);
structure IntStack : MONO_STACK?
- IntStack.push(1, IntStack.empty);
val it = - : IntStack.t
and so forth. It seems to work fine so far. Now, I want to define a module that
parameterizes over this functor. So I have defined a funsig for the
Collect.Stack.Mono functor (which can be seen in my repo). Then, following the
pattern indicated above, I tried to define the following test module:
(* load my little utility library *)
CM.autoload("../../../utils/sources.cm");
functor T (functor StackFn:MONO_STACK) =
struct
structure S = StackFn (type elem = int)
val x = S.push (1, S.empty)
end
But this won't compile! I get a type error:
Error: operator and operand don't agree [overload conflict]
operator domain: S.elem * S.t
operand: [int ty] * S.t
in expression:
S.push (1,S.empty)
uncaught exception Error
raised at: ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
../compiler/TopLevel/interact/evalloop.sml:44.55
../compiler/TopLevel/interact/evalloop.sml:292.17-292.20
Yet, inside functor T, I appear to be using the exact same instantiation
pattern that works perfectly at the top level. What am I missing?
Unfortunately, that's not the end of my mishaps. Now, I remove the line
causing the type error, leaving,
functor T (functor StackFn:MONO_STACK) =
struct
structure S = StackFn (type elem = int)
end
This compiles fine:
[scanning ../../../utils/sources.cm]
val it = true : bool
[autoloading]
[autoloading done]
functor T(<param>: sig functor StackFn : <fctsig> end) :
sig
structure S : <sig>
end
val it = () : unit
But I cannot actually instantiate the module! Apparently the path access syntax
is unsupported for higher order functors?
- structure Test = T (functor Collect.Stack.Mono);
stdIn:43.36-43.43 Error: syntax error: deleting DOT ID DOT
I am at a lost.
Questions
I have three related questions:
Is there a basic principle of higher-order functors in SML/NJ that I'm
missing, or is it just an incompletely, awkwardly implemented feature of the
language?
If the latter, where can I turn for more elegant and practicable higher order
functors? (Hopefully an SML, but I'll dip into OCaml if necessary.)
Is there perhaps a different approach I should taking to achieve these kinds
of effects that avoids higher order functors all together?
Many thanks in advance for any answers, hints, or followup questions!
Regarding your first attempt, the right syntax to apply your IntSetFn functor is:
structure IntSet = IntSetFn (functor SetFn = ListSetFn)
The same applies to your application of the Test functor in the second attempt:
structure Test = T (functor StackFn = Collect.Stack.Mono)
That should fix the syntax errors.
The type error you get when trying to use your stack structure S inside functor T has to do with the way you defined the MONO_STACK funsig:
funsig MONO_STACK (E:ELEM) = MONO_STACK
This just says that it returns a MONO_STACK structure, with a fully abstract elem type. It does not say that its elem type is gonna be the same as E.elem. According to that, I would able to pass in a functor like
functor F (E : ELEM) = struct type elem = unit ... end
to your functor T. Hence, inside T, the type system is not allowed to assume that type S.elem = int, and consequently you get a type error.
To fix this, you need to refine the MONO_STACK funsig as follows:
funsig MONO_STACK (E:ELEM) = MONO_STACK where type elem = E.elem
That should eliminate the type error.
[Edit]
As for your questions:
Higher-order functors are a little awkward syntactically in SML/NJ because it tries to stay 100% compatible with plain SML, which separates the namespace of functors from that for structures. If that wasn't the case then there wouldn't be the need for funsigs as a separate namespace either (and other syntactic baroqueness), and the language of signatures could simply be extended to include functor types.
Moscow ML is another SML dialect with a higher-order module extension that resolves the compatibility issue somewhat more elegantly (and is more expressive). There also was (now mostly dead) ALice ML, yet another SML dialect with higher-order functors that simply dropped the awkward namespace separation. OCaml of course did not have this constraint in the first place, so its higher-order modules are also more regular syntactically.
The approach seems fine.

Understanding functors in OCaml

I'm quite stuck with the following functor problem in OCaml. I paste some of the code just to let you understand. Basically
I defined these two modules in pctl.ml:
module type ProbPA = sig
include Hashtbl.HashedType
val next: t -> (t * float) list
val print: t -> float -> unit
end
module type M = sig
type s
val set_error: float -> unit
val check: s -> formula -> bool
val check_path: s -> path_formula -> float
val check_suite: s -> suite -> unit
end
and the following functor:
module Make(P: ProbPA): (M with type s = P.t) = struct
type s = P.t
(* implementation *)
end
Then to actually use these modules I defined a new module directly in a file called prism.ml:
type state = value array
type t = state
type value =
| VBOOL of bool
| VINT of int
| VFLOAT of float
| VUNSET
(* all the functions required *)
From a third source (formulas.ml) I used the functor with Prism module:
module PrismPctl = Pctl.Make(Prism)
open PrismPctl
And finally from main.ml
open Formulas.PrismPctl
(* code to prepare the object *)
PrismPctl.check_suite s.sys_state suite (* error here *)
and compiles gives the following error
Error: This expression has type Prism.state = Prism.value array
but an expression was expected of type Formulas.PrismPctl.s
From what I can understand there a sort of bad aliasing of the names, they are the same (since value array is the type defined as t and it's used M with type s = P.t in the functor) but the type checker doesn't consider them the same.
I really don't understand where is the problem, can anyone help me?
Thanks in advance
(You post non-compilable code. That's a bad idea because it may make it harder for people to help you, and because reducing your problem down to a simple example is sometimes enough to solve it. But I think I see your difficulty anyway.)
Inside formulas.ml, Ocaml can see that PrismPctl.s = Pctl.Make(Prism).t = Prism.t; the first equality is from the definition of PrismPctl, and the second equality is from the signature of Pctl.Make (specifically the with type s = P.t bit).
If you don't write an mli file for Formulas, your code should compile. So the problem must be that the .mli file you wrote doesn't mention the right equality. You don't show your .mli files (you should, they're part of the problem), but presumably you wrote
module PrismPctl : Pctl.M
That's not enough: when the compiler compiles main.ml, it won't know anything about PrismPctl that's not specified in formulas.mli. You need to specify either
module PrismPctl : Pctl.M with type s = Prism.t
or, assuming you included with type s = P.t in the signature of Make in pctl.mli
module PrismPctl : Pctl.M with type s = Pctl.Make(Prism).s
This is a problem I ran into as well when learning more about these. When you create the functor you expose the signature of the functor, in this case M. It contains an abstract type s, parameterized by the functor, and anything more specific is not exposed to the outside. Thus, accessing any record element of s (as in sys_state) will result in a type error, as you've encountered.
The rest looks alright. It is definitely hard to get into using functors properly, but remember that you can only manipulate instances of the type parameterized by the functor through the interface/signature being exposed by the functor.