Skip to content

Commit

Permalink
Document pitfalls of Nullable, fixes #7, resolves #2
Browse files Browse the repository at this point in the history
  • Loading branch information
hdgarrood committed Jan 12, 2019
1 parent 885a873 commit f6e4973
Showing 1 changed file with 26 additions and 4 deletions.
30 changes: 26 additions & 4 deletions src/Data/Nullable.purs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,30 @@ import Data.Function.Uncurried (Fn3, runFn3)
import Data.Maybe (Maybe(..), maybe)
import Data.Ord (class Ord1)

-- | A nullable type.
-- | A nullable type. This type constructor is intended to be used for
-- | interoperating with JavaScript functions which accept or return null
-- | values.
-- |
-- | This type constructor may be useful when interoperating with JavaScript functions
-- | which accept or return null values.
-- | The runtime representation of `Nullable T` is the same as that of `T`,
-- | except that it may also be `null`. For example, the JavaScript values
-- | `null`, `[]`, and `[1,2,3]` may all be given the type
-- | `Nullable (Array Int)`. Similarly, the JavaScript values `[]`, `[null]`,
-- | and `[1,2,null,3]` may all be given the type `Array (Nullable Int)`.
-- |
-- | There is one pitfall with `Nullable`, which is that values of the type
-- | `Nullable T` will not function as you might expect if the type `T` happens
-- | to itself permit `null` as a valid runtime representation.
-- |
-- | In particular, values of the type `Nullable (Nullable T)` will ‘collapse’,
-- | in the sense that the PureScript expressions `notNull null` and `null`
-- | will both leave you with a value whose runtime representation is just
-- | `null`. Therefore it is important to avoid using `Nullable T` in
-- | situations where `T` itself can take `null` as a runtime representation.
-- | If in doubt, use `Maybe` instead.
-- |
-- | `Nullable` does not permit lawful `Functor`, `Applicative`, or `Monad`
-- | instances as a result of this pitfall, which is why these instances are
-- | not provided.
foreign import data Nullable :: Type -> Type

-- | The null value.
Expand All @@ -35,7 +55,9 @@ foreign import notNull :: forall a. a -> Nullable a
toNullable :: forall a. Maybe a -> Nullable a
toNullable = maybe null notNull

-- | Represent `null` using `Maybe a` as `Nothing`.
-- | Represent `null` using `Maybe a` as `Nothing`. Note that this function
-- | can violate parametricity, as it inspects the runtime representation of
-- | its argument (see the warning about the pitfall of `Nullable` above).
toMaybe :: forall a. Nullable a -> Maybe a
toMaybe n = runFn3 nullable n Nothing Just

Expand Down

0 comments on commit f6e4973

Please sign in to comment.