“Return type is incompatible” / Bad native declaration module error on applicative instance - frege

I’m reading the book "Haskell Programming from first principles" by Christopher Allen and Julie Moronuki and try to implement the code and examples in Frege.
Unfortunately, I run into compile errors on module level (in the eclipse editor) for the following code (Chapter 17 - Applicative; Chapter Exercises).
The error states the following:
Multiple messages at this line.
-The return type is incompatible with PreludeMonad.CApplicative<Exercises17.TThree<a,b,? >>.ƒpure(Lazy<b>)
-Java compiler errors are almost always caused by bad native declarations. When you're sure this is out of the question you've found a compiler bug, please report under https://github.com/frege/frege/issues and attach a copy of /Users/dkm/frege-workspace/frege_programming/bin/chapter17/Exercises17.java
-The parameterized method <b, a, b>pure(Monoid.CMonoid<a>, Monoid.CMonoid<b>, Lazy<b>) of type Exercises17.IApplicative_Three is not applicable for the arguments (Monoid.CMonoid<a>, Monoid.CMonoid<b>, Lazy<b>)
I tried the same code in Haskell, where I get no errors.
Reducing the code with the "undefined"-keywords did not solve the issue, so there seems to be some other problem with the structure of the instance itself.
data Three a b c = Three a b c
instance Functor (Three a b) where
fmap f (Three x y z) = Three x y (f z)
instance (Monoid a, Monoid b) => Applicative (Three a b) where
pure x = undefined
(Three a b f) <*> (Three c d x) = undefined
You can find the above code and other similar (failing as well as correctly compiling) examples as well here:
https://github.com/elrocqe/frege_programming/blob/15e3bc5c4748055dc7dc640677faa54d8e9539e3/src/chapter17/Exercises17.fr#L80
The applicative-instance I’m going for should eventually look like this:
instance (Monoid a, Monoid b) => Applicative (Three a b) where
pure x = Three mempty mempty x
(Three a b f) <*> (Three c d x) = (Three (mappend a c) (mappend b d) (f x))
As it works in Haskell, the expected result would be for it to compile in Frege too. Similar examples do compile correctly in Frege as well. (see repo above)
Can anybody give me a hint on what’s the issue here and how to fix it?
Thanks a lot in advance.

You must be using an outdated Frege compiler.
I suggest you get the latest compiler here: https://github.com/Frege/frege/releases/tag/3.25alpha
(I just tried the "Three" example, and it compiled ok)

Related

Prolog: consider clauses from a dynamic module when calling a predicate

In the SWI Prolog manual, I found the following remark:
For example, assume an application that can reason about multiple worlds. It is attractive to store the data of a particular world in a module, so we extract information from a world simply by invoking goals in this world.
This is actually a very good description of what I'm trying to achieve. However I ran into a problem. While I do want to model many different worlds, there are also things that I want to share across all of them. So my idea is to have an allworlds module for things that are true in every world, and one module for every world that I want to reason about, and the latter imports from the former. So I'd do something like this in the REPL:
allworlds:asserta(grandparent(X, Z) :- (parent(X, Y), parent(Y, Z))).
allworlds:dynamic(parent/2).
add_import_module(greece, allworlds, start).
greece:asserta(parent(kronos, zeus)).
greece:asserta(parent(zeus, ares)).
Now I'd like to query greece:grandparent(kronos, X) and get X = ares, but all I get is false. When allworlds:grandparent calls parent, it doesn't call greece:parent like I want it to, but allworlds:parent. My research seems to indicate that I need to make the grandparent predicate module-transparent. But calling allworlds:module_transparent(grandparent/2). didn't fix the issue, and it's also deprecated. This is where I'm stuck. How can I get this working? Is meta_predicate/1 part of the solution? Unfortunately I can't make heads or tails of its documentation.
Prolog modules don't provide a good solution for the "many worlds" design pattern. Notably, making the predicates meta-predicates (or module transparent or multifile) would be a problematic hack. But this pattern is trivial with Logtalk, which is a language extends Prolog and can use most Prolog systems as a backend compiler. A minimal (but not unique) solution for your problem is:
:- object(allworlds).
:- public(grandparent/2).
grandparent(X, Z) :-
::parent(X, Y),
::parent(Y, Z).
:- public(parent/2).
:- end_object.
:- object(greece,
extends(allworlds)).
parent(kronos, zeus).
parent(zeus, ares).
:- end_object.
Here, we use inheritance (the individual worlds inherit the common knowledge) and messages to self (the ::/1 control construct) when common predicates need to access world specific predicate definitions (self is the object/world that received the message - grandparent/2 in the example).
Assuming the code is saved in a worlds.lgt file and that you're using SWI-Prolog as the backend:
$ swilgt
...
?- {worlds}.
% [ /Users/pmoura/worlds.lgt loaded ]
% (0 warnings)
true.
?- greece::grandparent(kronos, X).
X = ares.
P.S. If running on windows, use the "Logtalk - SWI-Prolog" shortcut from the Start Menu after installing Logtalk.
I ultimately solved this by passing the module around explicitly and invoking predicates in it with the : operator. It reminds me a bit of doing OOP in C, where you do things like obj->vtable->method(obj, params) (note how obj is mentioned twice, just like the M in my code below).
Similar to the Logtalk solution, I need to explicitly call into the imported module when I want to consider its clauses. As an example, I've added the fact that a father is also a parent to the allworlds module.
allworlds:assertz(grandparent(M, X, Z) :- (M:parent(M, X, Y), M:parent(M, Y, Z))).
allworlds:assertz(parent(M, X, Y) :- M:father(M, X, Y)).
add_import_module(greece, allworlds, start).
greece:assertz(parent(_, kronos, zeus)).
% need to call into allworlds explicitly
greece:assertz(parent(M, X, Y) :- allworlds:parent(M, X, Y)).
greece:assertz(father(_, zeus, ares)).
After making these assertions, I can call greece:grandparent(greece, kronos, X). and get the expected result X = ares.

Error - unbound symbol modulo (Scheme) when using Repl online IDE

A homework problem needs me to calculate gcd of 2 numbers. But using the modulo keyword in the function for gcd gives the above error when run on Repl.it (online IDE).
I looked at other answers, but they don't exactly provide a solution to the problem. I tried to run the program using jdoodle.com (another online IDE) and it works perfectly there. So, I don't know why it won't work on Repl.
;; My gcd function
(define (gcd a b)
(cond
[
(= b 0) a
]
[else
(gcd b (modulo a b))
]
)
)
I would like to know why this doesn't work for Repl IDE and if there is any way how I can make it work there without simply switching to another website.
modulo function is not implemented in BiwaScheme used by repl.it. However good new is - mod function is! So, with some reasonable reformatting, this should work:
(define (gcd a b)
(cond [(= b 0) a]
[else (gcd b (mod a b))]))

Pointwise function equality proof [duplicate]

I'm just starting playing with idris and theorem proving in general. I can follow most of the examples of proofs of basic facts on the internet, so I wanted to try something arbitrary by my own. So, I want to write a proof term for the following basic property of map:
map : (a -> b) -> List a -> List b
prf : map id = id
Intuitively, I can imagine how the proof should work: Take an arbitrary list l and analyze the possibilities for map id l. When l is empty, it's obvious; when
l is non-empty it's based on the concept that function application preserves equality.
So, I can do something like this:
prf' : (l : List a) -> map id l = id l
It's like a for all statement. How can I turn it into a proof of the equality of the functions involved?
You can't. Idris's type theory (like Coq's and Agda's) does not support general extensionality. Given two functions f and g that "act the same", you will never be able to prove Not (f = g), but you will only be able to prove f = g if f and g are defined the same, up to alpha and eta equivalence or so. Unfortunately, things only get worse when you consider higher-order functions; there's a theorem about such in the Coq standard library, but I can't seem to find or remember it right now.

Should I leave non-function values in modules or bring them to the main program file?

This is a question about how I should organize my F# code. I hope it is not in violation of SO rules.
I have dozens of source files (names terminating in .fs) in my project. Each file contains a module. In some of these files/modules I define only functions. In others I define functions and other values (not functions).
The last file in the Solution Explorer (Visual Studio) is Program.fs which actually contains very little code. Most calculations have been done "above" it.
I am considering moving the non-function values declared in the other modules to Program.fs. These are the advantages and disadvantages I see from this change:
Advantages:
1) A better view of program flow.
2) Easier to select all code above a certain line and send it for execution in FSI.
3) Slightly easier to search for those values in the editor.
4) Possibly easier to debug by putting breakpoints on the lines where values are declared.
Disadvantages:
1) Program.fs could become large and unwieldy.
2) Loss of modularity.
3) After implementing the changes, if the calculation of value y in module B depends on value x in module A "above" it then I can no longer have y as a value, it must be declared as a function of x. Similarly if a function declaration in module B depends on a value in module A I must add a parameter to the function definition.
Below are two examples of the same small program created under the two alternative methods. Which of the two is better in general?
// ///////////////// Values in modules \\\\\\\\\\\\\\\\\\\\
// File A.fs
module A
let i = 1
let add x y : float = x + y
// File B.fs
module B
let sqr z = z * z + float i
let x = sqr 99.9
// File Program.fs
open A
open B
let y =
add (float i) x
|> sqr
printfn "%f" y
[<EntryPoint>]
let main argv =
printfn "%A" argv
0 // return an integer exit code
// This is the calculated value for y: 99640524.640100
// ///////////////// Values in Program.fs \\\\\\\\\\\\\\\\\\\\
// File A.fs
module A
let add x y : float = x + y
// File B.fs
module B
open A
let sqr i z = z * z + float i // notice the additional parameter
//File Program.fs
open A
open B
let i = 1
let x = sqr i 99.9
let y =
add (float i) x
|> sqr i
printfn "%f" y
[<EntryPoint>]
let main argv =
printfn "%A" argv
0 // return an integer exit code
// This is the calculated value for y: 99640524.640100
As you presented it, the second version (with values moved to Main) is better imho. You pretty much nailed it with the #1 advantage and it's a really big one. As for the disadvantages you listed:
Large main: Yeah, depends on how much stuff we're talking, worst case you could keep the values in yet another module used just by main and just for values. Think "Config module"
Loss of modularity: I can't see
why. If anything it increases the modularity? Your main does not
depend on module X having some value, it provides it. You can then swap the module with another satisfying the same interface and not care about ripple effect it could have on other modules. If you have a large hierarchy of modules you could look into representing it in your main as per dependency inversion principle - it would take some work but the good news is that in functional languages you don't need IoC containers, partial application does the job
If module B depends on a value existing in module A it isn't very modular to begin with, is it? It's a good thing that you will have to change it into a function - it will explicitly say what is now implicit
Note that I'm writing this from my mostly OOP experience, so in functional programming some of it may be not applicable

Prolog- singleton variable in branch warning

Hello here is my code in Prolog:
arc(a,h).
arc(b,c).
related_to(X, Ys) :-
setof(Y, arc(X, Y), Ys).
cut([H|T],Y) :-
check(H,Y),
T = [] -> cut(T,Y).
check(X,Y) :-
related_to(X,Xs),
member(Y,Xs) -> write('There is a road');
cut(Xs,Y).
When I am trying to run check(a,b) it doesn't run. I get the message
Singleton variable in branch: Xs
When I am not using cut question, I don't get any error. I would be grateful for pointing me where I made a mistake and showing way to repair it.
TL;DR: Prolog is right. And you really are doing the best taking the messages seriously.
You are using if-then-else in an unconventional manner. For this reason it is not that simple to figure out what is happening. When I say listing(check) I get the following:
check(A, B) :-
( related_to(A, C),
member(B, C)
-> write('There is a road')
; cut(C, B)
).
So Prolog was not very impressed by your indentation style, instead, it just looked for operators. In fact, the C (which is your original Xs) occurs in the if-part which is unrelated to the else-part. What you probably wanted is:
check(X,Y) :-
related_to(X,Xs),
( member(Y,Xs)
-> write('There is a road')
; cut(Xs,Y)
).
Regardless of the concrete problem at hand, I very much doubt that your code makes sense: Xs is a list of connected nodes, but do you really need this in this context? I do not think so.
Why not use closure0/3 to determine connectedness:
?- closure0(arc, A, B).
BTW, it is not clear whether you consider a directed graph or an undirected one. Above works only for directed graphs, for undirected graphs rather use:
comm(P_2, A,B) :-
( call(P_2, A,B)
; call(P_2, B,A)
).
?- closure0(comm(arc), A, B).
If you are interested in the path as well, use path/4:
?- path(comm(arc), Path, A, B).