[m-dev.] Mercury and C#

Peter Ross peter.ross at miscrit.be
Sat Jun 9 01:06:19 AEST 2001


Hi,

One more major step along the path to full .NET integration has been
achieved.

I have defined a class Person in C#.

Inherited this class Person in Mercury to create a new class Employee
which is exported.

I then called this exported class from C# again, to give the following
output.

$ ./use_employee.exe
Employee Peter earns 5
but I decided to give Peter a raise because
he got C# and Mercury talking.
Employee Peter earns 15

Find attached all the source code that was used to generate this
example.

Pete
-------------- next part --------------
namespace Person
{
    using System;

    public class Person
    {
        public Person()
        {
        }

		private string name;

		public string Name 
		{
			get 
			{
				return name;
			}
			set
			{
				name = value;
			}
		}
    }
}
-------------- next part --------------
%------------------------------------------------------------------------------%
%------------------------------------------------------------------------------%

:- module employee.

:- interface.

:- typeclass 'Employee'(T) <= 'Person'(T) where [
	pred 'Salary'(int, T, T),
	mode 'Salary'(in, di, uo) is det,
	mode 'Salary'(out, di, uo) is det
].

:- type employee.
:- instance 'Employee'(employee).
:- instance 'Person'(employee).
:- instance 'Object'(employee).

:- func new(int) = employee.
:- mode new(di) = uo is det.

%------------------------------------------------------------------------------%

:- implementation.

:- import_module 'mscorlib_mercury', 'mscorlib_mercury__mObject'.
:- import_module 'Person_mercury', 'Person_mercury__mPerson'.

%------------------------------------------------------------------------------%

:- pragma foreign_class(
	'Employee'(employee),
	new/1,
	"Employee"
).

:- type employee
	--->	employee(
			person	:: 'Person.Person',
			salary	:: int
		).

:- instance 'Employee'(employee) where [
	pred('Salary'/3) is salary
].
:- instance 'Person'(employee) where [
	pred('Name'/3) is name
].
:- instance 'Object'(employee) where [
].

new(S) = employee(new, S).

:- pred salary(int, employee, employee).
:- mode salary(in, di, uo) is det.
:- mode salary(out, di, uo) is det.

:- pragma promise_pure(salary/3).
salary(S::in, employee(P, _)::di, employee(P, NewS)::uo) :-
	unsafe_promise_unique(S, NewS).
salary(S::out, employee(P, S)::di, employee(P, NewS)::uo) :-
	unsafe_promise_unique(S, NewS).

:- pred name(string, employee, employee).
:- mode name(in, di, uo) is det.
:- mode name(out, di, uo) is det.

name(Name, employee(P0, S), employee(P, S)) :-
	'Name'(Name, P0, P).

%------------------------------------------------------------------------------%
%------------------------------------------------------------------------------%
-------------- next part --------------
namespace use_employee
{
    using System;
    using employee;

    public class use_employee
    {
        public static void Main(string[] args)
        {
            employee.Employee e = new employee.Employee(5);
            e.Name = "Peter";

            WriteSalary(e);

            Console.Write("but I decided to give ");
            Console.Write(e.Name);
            Console.WriteLine(" a raise because ");
            Console.WriteLine("he got C# and Mercury talking.");

            e.Salary(15);
            WriteSalary(e);
        }

        public static void WriteSalary(employee.Employee e)
        {
            int x = 0;
            e.Salary(ref x);
            Console.Write("Employee ");
            Console.Write(e.Name);
            Console.Write(" earns ");
            Console.WriteLine(x);
            
        }
    }

}


More information about the developers mailing list