Skip to content

LYAH adaptions for Frege

Ingo Wechsung edited this page Mar 2, 2015 · 28 revisions

This document is for those who want to learn Frege by going through Learn you a Haskell while doing the exercises in Frege. It will help you to overcome obstacles that stem from differences between both languages and the tools used. As small as those differences are, they’re probably sufficient to confuse and discourage someone who is just starting.

Hence, for every example, explanation or exercise that doesn’t work the same way in Frege as described in LYAH, there will be a remark here. Chapter and Section titles will be included for better orientation, as well as a short quote to establich the context for our comments. This is so that if you stumble upon some difficulty, say, in Chapter 2 “Starting out” and Section “Texas ranges”, you would easily find whether there is something here under those headings.

However, if the difference is recurring often (like, for example, that you must write true in Frege instead of True like in Haskell), it won’t be mentioned again after some time.

Nobody is perfect, and so are the authors of this wiki page. If you miss something, find something inaccurate or not detailed enough, please let us know by opening an issue in the Frege project.

This wiki page is done in admiration of the LYAH author, Miran Lipovača, who licensed his work with the Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. This allows us to build upon his material, provided that the same license applies to the derived work, which we herewith declare to be the case.

Why are there differences anyway?

The objective in the devlopment of Frege was that it should be a practical language on the JVM platform while being as close to Haskell as possible. This means, among other things, that interoperability with Java and other JVM languages should be seamless. As important as Haskell compatibility is, it is simply not fully achievable for various reasons, at least not without making the language impractical in this respect.

Adaption to the JVM platform is the key reason for various differences concerning basic types (Bool, String), low-level system functions, the module system and the foreign function interface, which is specialised on JVM languages.

Another reason is that one can do only so much. Look how many (and ingenious) people work on GHC! You simply can’t match this with a handful of hobbyists who develop Frege in their spare time. This is why Frege is more or less on par with Haskell 2010, but doesn't have many of the advanced features of GHC Haskell.

But now let’s jump right into LYAH!

Chapter 1. Introduction

What you need to dive in

Instead of ghci we use a similar tool which is known as Frege REPL. The only prerequisite for this is a Java7 (or higher) installation. You can check your java version like this:

$ java -version

Here is how you install and run the Frege REPL:

  • Download the latest distribution from the REPL download page.

  • Unzip the archive. This is done best in some directory dedicated solely to the REPL. After unzipping, it should look like this (apart from differences in the version numbers):

    $ cd repl
    $ unzip ~/Downloads/frege-repl-1.1.1-SNAPSHOT.zip 
    Archive:  /home/ingo/Downloads/frege-repl-1.1.1-SNAPSHOT.zip
    [ ... snipped ... ]
    $ tree
    .
    ├── frege-repl-1.1.1-SNAPSHOT.jar
    └── lib
        ├── ecj-4.2.2.jar
        ├── frege-3.22.367-g2737683.jar
        ├── frege-interpreter-core-1.0.3-SNAPSHOT.jar
        ├── frege-interpreter-java-support-1.0.3-SNAPSHOT.jar
        ├── frege-repl-nativedeps-1.1.1-SNAPSHOT.jar
        └── jline-2.12.jar
    $ pwd
    /home/ingo/repl

The command to run this no matter what your current working directory is, would be:

$ java -Xss4m -Xmx1g -jar /home/ingo/repl/frege-repl-1.1.1-SNAPSHOT.jar -terminal jline

It is recommended to make this a shell alias, like

$ alias frepl='java -Xss4m -Xmx1g -jar /home/ingo/repl/frege-repl-1.1.1-SNAPSHOT.jar -terminal jline'

This way you just type frepl and that's it. The -terminal jline adds command history and command editing capabilities. This may not work on Windows. OTOH, the Windows cmd.exe can be configured to do the same, so you can remove the -terminal jline.

The Fast Way: The Online REPL

An even faster way to dive in may be the online version of the REPL. It's just one click away, and will be fine for the first exercises!

Chapter 2: Starting Out

Ready, set, go!

Congratulations, you're in GHCI!

Not surprisingly, the greeting of the Frege REPL is a bit different:

$ frepl   # you did make that alias, didn't you?
Welcome to Frege 3.22.367-g2737683 (Oracle Corporation OpenJDK Server VM, 1.8.0_40-internal)
frege> 2+2
4

The prompt is frege> for the time being, and cannot be changed. To get help, enter :help. Note that after starting the program, it will need a few seconds to answer even simple questions as 2+2. The reason is that the JVM needs to warm up a bit. Later on, the delays will get shorter.


If we want to have a negative number, it's always best to surround it with parentheses.

Indeed. Though, Frege doesn't have problems with

frege> 5 * -3
-15
frege> -5 * 3
-15
frege> -5 * -3
15

but this will only work in infix expressions. So, when in doubt, surround negative numbers with parentheses.

One more thing: you must set apart operators by at least one space character, lest the following happens:

frege> 5*-3
[ERROR: 4]: E <console>.fr:4: can't resolve `*-`, did you mean `*` perhaps?

Boolean algebra is also pretty straightforward.

frege> True || False
[ERROR: 4]: E <console>.fr:4: can't resolve `True`, did you mean `Byte` perhaps?
[ERROR: 4]: E <console>.fr:4: can't resolve `False`, did you mean `File` perhaps?

In Frege, we must always write true and false instead of True and False. This is because we use the primitive boolean type of the JVM, which appears as an abstract type Bool in Frege. Consequently, we also have the boolean literals true and false.

Confusing? Don't panic! A deeper explanation follows later, when we learn about algebraic data types. Please just mark this for now: write true and false, not True and False.

frege> true || false
true

5 /= 5

We can as well write != in Frege, but /= still works for Haskell compatibility. (To my knowledge, no other language uses /= for not equal.)


"hello" == "hello"

Remark for Java programmers: this actually compares the values, not the references, as Java would do. That is, this is equivalent to the Java expression:

"hello".equals("hello")
Clone this wiki locally