Skip to content

Commit

Permalink
Merge pull request #418 from JordanMartinez/development
Browse files Browse the repository at this point in the history
Make next minor release: PS-0.13.x-v0.21.1
  • Loading branch information
JordanMartinez committed Dec 22, 2019
2 parents d73959a + 564d939 commit 31a08d9
Show file tree
Hide file tree
Showing 19 changed files with 2,053 additions and 1,253 deletions.
8 changes: 7 additions & 1 deletion 00-Getting-Started/04-Other-Important-Info.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@ Then, you use a search query like the following:

## Documenation

- Anytime you need to look up the documentation for a package, use [Pursuit](http://pursuit.purescript.org/). Be aware that some of the deprecated packages mentioned above are still posted there.
- Anytime you need to look up the documentation for a package, you have two options:
- use [Pursuit](http://pursuit.purescript.org/).
- Pros: One can navigate through a library's version and dependencies
- Cons: Some of the deprecated packages mentioned above are still posted there. (e.g. `purescript-dom-*` packages, which are deprecated in favor of `purescript-web-*` packages)
- use [Starsuit](https://spacchetti.github.io/starsuit/index.html)
- Pros: Only provides documentation for packages in the latest package set
- Cons: One does not immediately know which version of a library is displayed, nor what its dependencies are.
- Use the [same instructions used by Hoogle](https://github.com/ndmitchell/hoogle/blob/master/README.md#chrome-integration) to add Pursuit as a search engine to your web browser.
- Read [Pursuit's Search Help page](https://pursuit.purescript.org/help/users#searching)
- Some libraries have not been updated to `0.13.5` and are still on the `0.11.7` release. Some still work; others won't. In this work, we will insure that you do not use any such libraries, but be aware of that if you browse the docs on your own.
Expand Down
18 changes: 11 additions & 7 deletions 11-Syntax/01-Basic-Syntax/spago.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
Welcome to a Spago project!
You can edit this file as you like.
-}
{ sources =
[ "src/**/*.purs" ]
, name =
"untitled"
{ sources = [ "src/**/*.purs" ]
, name = "untitled"
, dependencies =
[ "console", "effect", "newtype", "partial", "prelude", "psci-support" ]
, packages =
../../packages.dhall
[ "console"
, "effect"
, "newtype"
, "partial"
, "prelude"
, "psci-support"
, "unsafe-coerce"
]
, packages = ../../packages.dhall
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
module Syntax.Basic.Typeclass.InstanceChains where

-- ## Instance Chains: Syntax

import Prelude -- imports the '+' operation below...

data Type1 = Type1
data Type2 = Type2
data Type3 = Type3

class ExampleClass1 theType

-- Instance chains are a workaround to the problem of "overlapping instances."
-- Here's how the syntax works:
instance name1 :: ExampleClass1 Type1
else instance name2 :: ExampleClass1 Type2
-- ...
else instance name3 :: ExampleClass1 Type3

-- For readability, the `else` and `instance` keywords can appear on
-- their own line or with a newline separating the keywords
class ExampleClass2 theType

instance nameA :: ExampleClass2 Type1
else
instance nameB :: ExampleClass2 Type2
else

instance nameC :: ExampleClass2 Type3

-- ## Instance Chains: Use Cases

-- Instance chains are useful because they allow you to define multiple
-- instances for a given type class, but define the order in which the
-- type class constraint is solved.

data SomeRandomType
= FirstValue
| SecondValue

class ProduceAnInt a where
mkInt :: a -> Int

-- When solving for `ProduceAnInt someType`, the compiler will
-- solve for `someType` in the following order:
instance tryMeFirst :: ProduceAnInt Int where
mkInt theInt = theInt
else
instance tryMeSecond :: ProduceAnInt String where
mkInt _ = 13
else
instance tryMeThird :: ProduceAnInt SomeRandomType where
mkInt FirstValue = 89
mkInt SecondValue = 98
else
instance catchAll :: ProduceAnInt allOtherPossibleTypes where
mkInt _ = 42

data HasNoInstance = HasNoInstance

example :: Int
example =
(mkInt 1 ) + (mkInt "foo") + (mkInt FirstValue) + (mkInt HasNoInstance) {-
which, once the constraints are solved, will be the same as computing
(1) + (13) + (89) + (42) -}


-- ## Instance Chains Gotchas: No Backtracking

-- Given the following type class

class Stringify a where
stringify :: a -> String

-- One might write an instance chain like so with the following idea:
-- 1. First attempt to show the item using that type class instance
-- 2. Otherwise, indicate that it cannot be shown.

instance doMeFirst :: (Show allPossibleTypes) => Stringify allPossibleTypes where
stringify a = show a
else
instance defaultToMeOtherwise :: Stringify a where
stringify _ = "The value could not be converted into a String."

-- Then, one might attempt to use that code like so:
data Foo = Foo

-- failsToCompile :: String
-- failsToCompile = stringify "a normal string" <> stringify Foo

{-
Uncommenting that will produce the following compiler error:
No type class instance was found for
Data.Show.Show Foo
while applying a function stringify
of type Stringify t0 => t0 -> String
to argument Foo
while checking that expression stringify Foo
has type String
in value declaration failsToCompile
where t0 is an unknown type
-}

-- Why does this occur? Because the `doMeFirst` instance will match on
-- every type since the parameter passed to Stringify is literally
-- `allPossibleTypes`. It will then attempt to find the `Show` instance
-- for `allPossibleTypes`. In the case of `Foo`, which does not
-- have such an instance, the compiler does not "backtrack" and
-- attempt to use the `defaultToMeOtherwise` instance. Rather, it immediately
-- fails with the above error.
-- Backtracking is a feature that has not yet been implemented in the
-- compiler.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Gotchas

The rest of this folder will cover a few "gotchas" that can occur when you're working with type classes. Some of the code in these examples will be commented out because it will fail to compile.
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
module Syntax.Basic.Typeclass.Gotchas.TypeEqualityNotPropagate where

import Unsafe.Coerce (unsafeCoerce)

-- ## Gotcha Number 1: Type Equality isn't yet included in Type Class Constraints

-- ### Example of the Problem

-- Given a type class like so...
class TwoTypesButTheyAreTheSameThing a b | a -> b, b -> a

-- and an instance like so...
instance exampleTypeClass :: TwoTypesButTheyAreTheSameThing Int Int

-- ... the below code will fail to compile
{-
foo :: forall int
. TwoTypesButTheyAreTheSameThing Int int
=> int
foo = 8
Compiler Error:
Could not match type
Int
with type
int0
while checking that type Int
is at least as general as type int0
while checking that expression 8
has type int0
in value declaration foo
where sameAsInt0 is a rigid type variable
bound at (line 9, column 7 - line 9, column 8)
-}

-- Why? Because the compiler does not also infer that `int` must be
-- the type, `Int`, when solving the type class constraint, even if the
-- instance and type class' functional dependencies indicate otherwise.

-- ### Current Workaround

class A_Determines_B a b | a -> b

instance aDeterminesB :: A_Determines_B Int String

-- The below "foreign import" syntax will be covered more in the FFI folder
foreign import data Computed :: Type -> Type

fromComputed :: forall a b. A_Determines_B a b => Computed a -> b
fromComputed = unsafeCoerce

toComputed :: forall a b. A_Determines_B a b => b -> Computed a
toComputed = unsafeCoerce

-- As hdgarood explained it,
-- "This is safe because you have to tell the compiler that you have an
-- `A_Determines_B a b` instance before it will coerce between the `a` and `b`.
-- But yes it’s expected that constraints with fundeps don’t propagate
-- type equalities. That’s not yet implemented."
2 changes: 1 addition & 1 deletion 21-Hello-World/04-Foldable-Traversable/ReadMe.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Foldable Traversable

This folder is still a Work In Progress because it originally existed in a different location in this repository.
This folder will overview the `purescript-foldable-traversable` and `purescript-filterable` libraries. Together, these libraries provide most of the functions one would use when working with collections.

These two type classes are being overviewed because their concepts will arise later in the "Hello World" folder. Rather than explaining them there when we need them, we'll explain them here so that they are more familiar when we get to them there.
17 changes: 10 additions & 7 deletions 21-Hello-World/04-Foldable-Traversable/spago.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
Welcome to a Spago project!
You can edit this file as you like.
-}
{ name =
"my-project"
{ name = "my-project"
, dependencies =
[ "aff", "console", "effect", "foldable-traversable", "psci-support" ]
, packages =
../../packages.dhall
, sources =
[ "src/**/*.purs" ]
[ "aff"
, "console"
, "effect"
, "filterable"
, "foldable-traversable"
, "psci-support"
]
, packages = ../../packages.dhall
, sources = [ "src/**/*.purs" ]
}

0 comments on commit 31a08d9

Please sign in to comment.