Skip to content

Commit 68f99e0

Browse files
committed
Merge pull request #54 from plaid/dc-readme
readme: update error messages
2 parents 97b7e60 + 5340af6 commit 68f99e0

File tree

1 file changed

+134
-27
lines changed

1 file changed

+134
-27
lines changed

README.md

Lines changed: 134 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,31 @@ _add('2', '2');
121121

122122
```javascript
123123
add('2', '2');
124-
// ! TypeError: ‘add’ expected a value of type Number as its first argument; received "2"
124+
// ! TypeError: Invalid value
125+
//
126+
// add :: Number -> Number -> Number
127+
// ^^^^^^
128+
// 1
129+
//
130+
// 1) "2" :: String
131+
//
132+
// The value at position 1 is not a member of ‘Number’.
125133
```
126134

127135
Type checking is performed as arguments are provided (rather than once all
128136
arguments have been provided), so type errors are reported early:
129137

130138
```javascript
131139
add('X');
132-
// ! TypeError: ‘add’ expected a value of type Number as its first argument; received "X"
140+
// ! TypeError: Invalid value
141+
//
142+
// add :: Number -> Number -> Number
143+
// ^^^^^^
144+
// 1
145+
//
146+
// 1) "X" :: String
147+
//
148+
// The value at position 1 is not a member of ‘Number’.
133149
```
134150

135151
### Types
@@ -450,7 +466,17 @@ cmp('z', 'a');
450466
// => 1
451467

452468
cmp(0, '1');
453-
// ! TypeError: ‘cmp’ expected a value of type Number as its second argument; received "1"
469+
// ! TypeError: Type-variable constraint violation
470+
//
471+
// cmp :: a -> a -> Number
472+
// ^ ^
473+
// 1 2
474+
//
475+
// 1) 0 :: Number
476+
//
477+
// 2) "1" :: String
478+
//
479+
// Since there is no type of which all the above values are members, the type-variable constraint has been violated.
454480
```
455481

456482
#### `NullaryType`
@@ -496,10 +522,26 @@ rem(42, 5);
496522
// => 2
497523

498524
rem(0.5);
499-
// ! TypeError: ‘rem’ expected a value of type Integer as its first argument; received 0.5
525+
// ! TypeError: Invalid value
526+
//
527+
// rem :: Integer -> NonZeroInteger -> Integer
528+
// ^^^^^^^
529+
// 1
530+
//
531+
// 1) 0.5 :: Number
532+
//
533+
// The value at position 1 is not a member of ‘Integer’.
500534

501535
rem(42, 0);
502-
// ! TypeError: ‘rem’ expected a value of type NonZeroInteger as its second argument; received 0
536+
// ! TypeError: Invalid value
537+
//
538+
// rem :: Integer -> NonZeroInteger -> Integer
539+
// ^^^^^^^^^^^^^^
540+
// 1
541+
//
542+
// 1) 0 :: Number
543+
//
544+
// The value at position 1 is not a member of ‘NonZeroInteger’.
503545
```
504546

505547
#### `UnaryType`
@@ -516,7 +558,15 @@ sum([1, 2, 3, 4]);
516558
// => 10
517559

518560
sum(['1', '2', '3', '4']);
519-
// ! TypeError: ‘sum’ expected a value of type (Array Number) as its first argument; received ["1", "2", "3", "4"]
561+
// ! TypeError: Invalid value
562+
//
563+
// sum :: Array Number -> Number
564+
// ^^^^^^
565+
// 1
566+
//
567+
// 1) "1" :: String
568+
//
569+
// The value at position 1 is not a member of ‘Number’.
520570
```
521571

522572
To define a unary type `t a` one must provide:
@@ -574,7 +624,17 @@ fromMaybe(0, Nothing);
574624
// => 0
575625

576626
fromMaybe(0, Just('XXX'));
577-
// ! TypeError: ‘fromMaybe’ expected a value of type (Maybe Number) as its second argument; received Just("XXX")
627+
// ! TypeError: Type-variable constraint violation
628+
//
629+
// fromMaybe :: a -> Maybe a -> a
630+
// ^ ^
631+
// 1 2
632+
//
633+
// 1) 0 :: Number
634+
//
635+
// 2) "XXX" :: String
636+
//
637+
// Since there is no type of which all the above values are members, the type-variable constraint has been violated.
578638
```
579639

580640
#### `BinaryType`
@@ -648,7 +708,15 @@ showCard(Pair('A', '♠'));
648708
// => 'A♠'
649709

650710
showCard(Pair('X', ''));
651-
// ! TypeError: ‘showCard’ expected a value of type (Pair Rank Suit) as its first argument; received Pair("X", "♠")
711+
// ! TypeError: Invalid value
712+
//
713+
// showCard :: Pair Rank Suit -> String
714+
// ^^^^
715+
// 1
716+
//
717+
// 1) "X" :: String
718+
//
719+
// The value at position 1 is not a member of ‘Rank’.
652720
```
653721

654722
#### `EnumType`
@@ -669,11 +737,6 @@ For example:
669737
// TimeUnit :: Type
670738
const TimeUnit = $.EnumType(['milliseconds', 'seconds', 'minutes', 'hours']);
671739

672-
// env :: [Type]
673-
const env = $.env.concat([TimeUnit, $.ValidDate, $.ValidNumber]);
674-
675-
const def = $.create(true, env);
676-
677740
// convertTo :: TimeUnit -> ValidDate -> ValidNumber
678741
const convertTo =
679742
def('convertTo',
@@ -692,7 +755,15 @@ convertTo('seconds', new Date(1000));
692755
// => 1
693756

694757
convertTo('days', new Date(1000));
695-
// ! TypeError: ‘convertTo’ expected a value of type ("milliseconds" | "seconds" | "minutes" | "hours") as its first argument; received "days"
758+
// ! TypeError: Invalid value
759+
//
760+
// convertTo :: ("milliseconds" | "seconds" | "minutes" | "hours") -> ValidDate -> ValidNumber
761+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
762+
// 1
763+
//
764+
// 1) "days" :: String
765+
//
766+
// The value at position 1 is not a member of ‘("milliseconds" | "seconds" | "minutes" | "hours")’.
696767
```
697768

698769
#### `RecordType`
@@ -711,18 +782,12 @@ RecordType :: {Type} -> Type
711782
For example:
712783

713784
```javascript
714-
// FiniteNumber :: Type
715-
const FiniteNumber = $.NullaryType(
716-
'my-package/FiniteNumber',
717-
x => Object.prototype.toString.call(x) === '[object Number]' && isFinite(x)
718-
);
719-
720785
// Point :: Type
721-
const Point = $.RecordType({x: FiniteNumber, y: FiniteNumber});
786+
const Point = $.RecordType({x: $.FiniteNumber, y: $.FiniteNumber});
722787

723788
// dist :: Point -> Point -> FiniteNumber
724789
const dist =
725-
def('dist', {}, [Point, Point, FiniteNumber],
790+
def('dist', {}, [Point, Point, $.FiniteNumber],
726791
(p, q) => Math.sqrt(Math.pow(p.x - q.x, 2) + Math.pow(p.y - q.y, 2)));
727792

728793
dist({x: 0, y: 0}, {x: 3, y: 4});
@@ -732,10 +797,26 @@ dist({x: 0, y: 0}, {x: 3, y: 4, color: 'red'});
732797
// => 5
733798

734799
dist({x: 0, y: 0}, {x: NaN, y: NaN});
735-
// ! TypeError: ‘dist’ expected a value of type { x :: FiniteNumber, y :: FiniteNumber } as its second argument; received {"x": NaN, "y": NaN}
800+
// ! TypeError: Invalid value
801+
//
802+
// dist :: { x :: FiniteNumber, y :: FiniteNumber } -> { x :: FiniteNumber, y :: FiniteNumber } -> FiniteNumber
803+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
804+
// 1
805+
//
806+
// 1) {"x": NaN, "y": NaN} :: Object, StrMap Number
807+
//
808+
// The value at position 1 is not a member of ‘{ x :: FiniteNumber, y :: FiniteNumber }’.
736809

737810
dist(0);
738-
// ! TypeError: ‘dist’ expected a value of type { x :: FiniteNumber, y :: FiniteNumber } as its first argument; received 0
811+
// ! TypeError: Invalid value
812+
//
813+
// dist :: { x :: FiniteNumber, y :: FiniteNumber } -> { x :: FiniteNumber, y :: FiniteNumber } -> FiniteNumber
814+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
815+
// 1
816+
//
817+
// 1) 0 :: Number
818+
//
819+
// The value at position 1 is not a member of ‘{ x :: FiniteNumber, y :: FiniteNumber }’.
739820
```
740821

741822
### Type classes
@@ -758,7 +839,17 @@ _concat([1, 2], [3, 4]);
758839
// => [1, 2, 3, 4]
759840

760841
_concat([1, 2], 'buzz');
761-
// ! TypeError: ‘_concat’ expected a value of type (Array Number) as its second argument; received "buzz"
842+
// ! TypeError: Type-variable constraint violation
843+
//
844+
// _concat :: a -> a -> a
845+
// ^ ^
846+
// 1 2
847+
//
848+
// 1) [1, 2] :: Array Number
849+
//
850+
// 2) "buzz" :: String
851+
//
852+
// Since there is no type of which all the above values are members, the type-variable constraint has been violated.
762853
```
763854

764855
The type of `_concat` is misleading: it suggests that it can operate on any
@@ -793,10 +884,26 @@ concat([1, 2], [3, 4]);
793884
// => [1, 2, 3, 4]
794885

795886
concat({}, {});
796-
// ! TypeError: ‘concat’ requires ‘a’ to implement Semigroup; Object does not
887+
// ! TypeError: Type-class constraint violation
888+
//
889+
// concat :: Semigroup a => a -> a -> a
890+
// ^^^^^^^^^^^ ^
891+
// 1
892+
//
893+
// 1) {} :: Object, StrMap ???
894+
//
895+
// ‘concat’ requires ‘a’ to satisfy the Semigroup type-class constraint; the value at position 1 does not.
797896

798897
concat(null, null);
799-
// ! TypeError: ‘concat’ requires ‘a’ to implement Semigroup; Null does not
898+
// ! TypeError: Type-class constraint violation
899+
//
900+
// concat :: Semigroup a => a -> a -> a
901+
// ^^^^^^^^^^^ ^
902+
// 1
903+
//
904+
// 1) null :: Null
905+
//
906+
// ‘concat’ requires ‘a’ to satisfy the Semigroup type-class constraint; the value at position 1 does not.
800907
```
801908

802909
Multiple constraints may be placed on a type variable by including multiple

0 commit comments

Comments
 (0)