Skip to content

0.7 Migration Guide

Gary Burgess edited this page Jul 13, 2015 · 12 revisions

The 0.7 ("Meltdown") release contains some major changes to the compiler and core libraries, which will make most code break. This guide should help you to update your libraries.

Build Process

The psc and psc-make executables have been replaced with psc (previously psc-make) and psc-bundle.

If you were previously using gulp-purescript or Pulp to build your library, you should be able to simply upgrade that tool to the latest version. An example gulpfile.js file can be found here.

If you were building your library directly, you will need to learn the new psc options, and how to use psc-bundle if you are bundling your code for the browser.

Invoking psc directly is now much simpler, since psc now supports globs as filename arguments. Simply provide globs for all PureScript source files, and for all foreign modules with --ffi:

psc 'src/**/*.purs' 
    'bower_components/purescript-*/src/**/*.purs'
    --ffi 'src/**/*.js' 
    --ffi 'bower_components/purescript-*/src/**/*.js'

Numeric Literals

Int and Number literals are now separate, and disambiguated syntactially: Number values must now be written with a decimal place.

1 :: Int
1.0 :: Number

You might see type errors like "Cannot unify Int with Number". Simply decide which of the two types is more appropriate in each case, and add or remove .0 as necessary.

Core Libraries

Prelude Import

The Prelude module is no longer imported automatically, and must be imported the same way as any other module. Simply add

import Prelude

to the top of your module.

Prelude as a Library

The Prelude modules are no longer bundled with the compiler. You have to install the appropriate libraries using Bower (or some other tool):

You might see this error when loading PSCi:

PSCi requires the `purescript-console` module to be installed.

To fix this, install purescript-console using Bower:

bower i purescript-console

and load the installed modules using your .psci file.

No More Class Operators

Core library type classes have been updated to use alphanumeric names for their members, instead of infix operators:

Module Name Operator Name Function Name
Prelude <$> map
<*> apply
>>= bind
<<< compose
<> append
+ add
* mul
- sub
/ div
== eq
&& conj
`
Control.Alt `< >`
Control.Comonad <<= extend
Data.Foreign.Index ! ix

Old operators have been kept as aliases, so for the most part, code should not break, but you do have to update your type class instances.

Consult the documentation for the new class definitions.

Declaring operators in classes will now produce a warning.

No more array sugar

[] syntax for array types has been removed. [] should now be written as Array, and [a] as Array a. It is still possible to use [] array literals, however:

ints :: Array Int
ints = [1, 2, 3]

Cons patterns for arrays have been removed due to their bad performance. If you previously used cons patterns, consider using a fold (if possible), or using a List or Seq instead. There is also a new function uncons in Data.Array (purescript-arrays) which works in more or less the same way as cons patterns did, but be aware that it is O(n).

Converting pre-0.7 code like the below to use uncons is straightforward:

f (x : xs) = something
f [] = somethingElse

Becomes:

f arr = case uncons arr of
  Just { head: x, tail: xs } -> something
  Nothing -> somethingElse

No more inline FFI code

Foreign JavaScript imports have been moved out into separate .js files, and are no longer defined inline with foreign import. This is to enable the transition to multiple backends, by reducing our dependence on explicit Javascript.

Foreign modules are passed to the compiler with the --ffi flag.

Values should be provided in the form exports.foo = ..., similar to a CommonJS module.

Each foreign module file should have a comment // module X.Y.Z where X.Y.Z is the name of the module it is associated with.

An example can be found here.

Clone this wiki locally