Skip to content

Commit c44fe5d

Browse files
committed
Drop IsForeign, general updates
1 parent 01424eb commit c44fe5d

25 files changed

+230
-472
lines changed

examples/Applicative.purs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,24 @@ import Control.Monad.Eff (Eff)
66
import Control.Monad.Eff.Console (CONSOLE, logShow)
77
import Control.Monad.Except (runExcept)
88

9-
import Data.Foreign (F)
10-
import Data.Foreign.Class (class IsForeign, readJSON, readProp)
9+
import Data.Foreign (F, Foreign, readNumber)
10+
import Data.Foreign.Index ((!))
11+
12+
import Example.Util.Value (foreignValue)
1113

1214
data Point = Point Number Number Number
1315

1416
instance showPoint :: Show Point where
1517
show (Point x y z) = "(Point " <> show [x, y, z] <> ")"
1618

17-
instance pointIsForeign :: IsForeign Point where
18-
read value = Point <$> readProp "x" value
19-
<*> readProp "y" value
20-
<*> readProp "z" value
19+
readPoint :: Foreign -> F Point
20+
readPoint value = do
21+
Point
22+
<$> (value ! "x" >>= readNumber)
23+
<*> (value ! "y" >>= readNumber)
24+
<*> (value ! "z" >>= readNumber)
2125

2226
main :: Eff (console :: CONSOLE) Unit
23-
main = logShow $ runExcept $
24-
readJSON """{ "x": 1, "y": 2, "z": 3 }""" :: F Point
27+
main =
28+
logShow $ runExcept $
29+
readPoint =<< foreignValue """{ "x": 1, "y": 2, "z": 3 }"""

examples/Arrays.purs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module Example.Arrays where
2+
3+
import Prelude
4+
5+
import Control.Monad.Eff (Eff)
6+
import Control.Monad.Eff.Console (CONSOLE, logShow)
7+
import Control.Monad.Except (runExcept)
8+
9+
import Data.Foreign (readArrayWith, readNumber, readString)
10+
11+
import Example.Util.Value (foreignValue)
12+
13+
main :: Eff (console :: CONSOLE) Unit
14+
main = do
15+
logShow $ runExcept $
16+
readArrayWith readString =<< foreignValue """["hello", "world"]"""
17+
logShow $ runExcept $
18+
readArrayWith readNumber =<< foreignValue """[1, 2, 3, 4]"""

examples/Complex.purs

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,43 @@ import Control.Monad.Eff (Eff)
66
import Control.Monad.Eff.Console (CONSOLE, logShow)
77
import Control.Monad.Except (runExcept)
88

9-
import Data.Foreign (F)
10-
import Data.Foreign.Class (class IsForeign, readJSON, readProp)
11-
import Data.Foreign.NullOrUndefined (unNullOrUndefined)
9+
import Data.Foreign (F, Foreign, readArray, readBoolean, readNumber, readString, readNullOrUndefined)
10+
import Data.Foreign.Index ((!))
11+
import Data.Traversable (traverse)
1212
import Data.Maybe (Maybe)
1313

14-
data SomeObject = SomeObject { foo :: String
15-
, bar :: Boolean
16-
, baz :: Number
17-
, list :: Array ListItem }
14+
import Example.Util.Value (foreignValue)
15+
16+
newtype SomeObject =
17+
SomeObject
18+
{ foo :: String
19+
, bar :: Boolean
20+
, baz :: Number
21+
, list :: Array ListItem
22+
}
1823

1924
instance showSomeObject :: Show SomeObject where
2025
show (SomeObject o) =
2126
"(SomeObject { foo: " <> show o.foo <>
2227
", bar: " <> show o.bar <>
2328
", baz: " <> show o.baz <>
2429
", list: " <> show o.list <>
25-
" })"
30+
"})"
2631

27-
instance objectIsForeign :: IsForeign SomeObject where
28-
read value = do
29-
foo <- readProp "foo" value
30-
bar <- readProp "bar" value
31-
baz <- readProp "baz" value
32-
list <- readProp "list" value
33-
pure $ SomeObject { foo: foo, bar: bar, baz: baz, list: list }
32+
readSomeObject :: Foreign -> F SomeObject
33+
readSomeObject value = do
34+
foo <- value ! "foo" >>= readString
35+
bar <- value ! "bar" >>= readBoolean
36+
baz <- value ! "baz" >>= readNumber
37+
list <- value ! "list" >>= readArray >>= traverse readListItem
38+
pure $ SomeObject { foo, bar, baz, list }
3439

35-
data ListItem = ListItem { x :: Number
36-
, y :: Number
37-
, z :: Maybe Number }
40+
newtype ListItem =
41+
ListItem
42+
{ x :: Number
43+
, y :: Number
44+
, z :: Maybe Number
45+
}
3846

3947
instance showListItem :: Show ListItem where
4048
show (ListItem o) =
@@ -43,14 +51,14 @@ instance showListItem :: Show ListItem where
4351
", z: " <> show o.z <>
4452
" })"
4553

46-
instance listItemIsForeign :: IsForeign ListItem where
47-
read value = do
48-
x <- readProp "x" value
49-
y <- readProp "y" value
50-
z <- unNullOrUndefined <$> readProp "z" value
51-
pure $ ListItem { x: x, y: y, z: z }
54+
readListItem :: Foreign -> F ListItem
55+
readListItem value = do
56+
x <- value ! "x" >>= readNumber
57+
y <- value ! "y" >>= readNumber
58+
z <- value ! "z" >>= readNullOrUndefined >>= traverse readNumber
59+
pure $ ListItem { x, y, z }
5260

5361
main :: Eff (console :: CONSOLE) Unit
5462
main = do
5563
let json = """{"foo":"hello","bar":true,"baz":1,"list":[{"x":1,"y":2},{"x":3,"y":4,"z":999}]}"""
56-
logShow $ runExcept $ readJSON json :: F SomeObject
64+
logShow $ runExcept $ readSomeObject =<< foreignValue json

examples/Either.purs

Lines changed: 0 additions & 33 deletions
This file was deleted.

examples/JSONArrays.purs

Lines changed: 0 additions & 15 deletions
This file was deleted.

examples/JSONSimpleTypes.purs

Lines changed: 0 additions & 21 deletions
This file was deleted.

examples/MaybeNullable.purs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ module Example.MaybeNullable where
33
import Prelude
44

55
import Control.Monad.Eff (Eff)
6-
import Control.Monad.Eff.Console (CONSOLE, log, logShow)
6+
import Control.Monad.Eff.Console (CONSOLE, logShow)
77
import Control.Monad.Except (runExcept)
88

9-
import Data.Foreign (F, unsafeFromForeign)
10-
import Data.Foreign.Class (readJSON, write)
11-
import Data.Foreign.Null (Null(..), unNull)
12-
import Data.Maybe (Maybe(..))
9+
import Data.Foreign (readBoolean, readNull)
10+
import Data.Traversable (traverse)
11+
12+
import Example.Util.Value (foreignValue)
1313

1414
-- Parsing values that are allowed to null or undefined is possible by
1515
-- using Maybe types.
1616
main :: Eff (console :: CONSOLE) Unit
1717
main = do
18-
logShow $ unNull <$> runExcept (readJSON "null" :: F (Null Boolean))
19-
logShow $ unNull <$> runExcept (readJSON "true" :: F (Null Boolean))
20-
log $ unsafeFromForeign $ write $ Null Nothing :: Null Boolean
21-
log $ unsafeFromForeign $ write $ Null $ Just true
18+
logShow $ runExcept $
19+
traverse readBoolean =<< readNull =<< foreignValue "null"
20+
logShow $ runExcept $
21+
traverse readBoolean =<< readNull =<< foreignValue "true"

examples/Nested.purs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import Control.Monad.Eff (Eff)
66
import Control.Monad.Eff.Console (CONSOLE, logShow)
77
import Control.Monad.Except (runExcept)
88

9-
import Data.Foreign (F)
10-
import Data.Foreign.Class (class IsForeign, readJSON, readProp)
11-
import Data.Foreign.Index (prop)
9+
import Data.Foreign (F, Foreign, readNumber, readString)
10+
import Data.Foreign.Index ((!), (!!))
11+
12+
import Example.Util.Value (foreignValue)
1213

1314
data Foo = Foo Bar Baz
1415

@@ -25,12 +26,13 @@ instance showBar :: Show Bar where
2526
instance showBaz :: Show Baz where
2627
show (Baz n) = "(Baz " <> show n <> ")"
2728

28-
instance fooIsForeign :: IsForeign Foo where
29-
read value = do
30-
s <- value # (prop "foo" >=> readProp "bar")
31-
n <- value # (prop "foo" >=> readProp "baz")
32-
pure $ Foo (Bar s) (Baz n)
29+
readFoo :: Foreign -> F Foo
30+
readFoo value = do
31+
s <- value ! "foo" !! "bar" >>= readString
32+
n <- value ! "foo" !! "baz" >>= readNumber
33+
pure $ Foo (Bar s) (Baz n)
3334

3435
main :: Eff (console :: CONSOLE) Unit
35-
main = do
36-
logShow $ runExcept $ readJSON """{ "foo": { "bar": "bar", "baz": 1 } }""" :: F Foo
36+
main =
37+
logShow $ runExcept $
38+
readFoo =<< foreignValue """{ "foo": { "bar": "bar", "baz": 1 } }"""

examples/Objects.purs

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,27 @@ module Example.Objects where
33
import Prelude
44

55
import Control.Monad.Eff (Eff)
6-
import Control.Monad.Eff.Console (CONSOLE, log, logShow)
6+
import Control.Monad.Eff.Console (CONSOLE, logShow)
77
import Control.Monad.Except (runExcept)
88

9-
import Data.Foreign (F, writeObject, unsafeFromForeign)
10-
import Data.Foreign.Class (class AsForeign, class IsForeign, (.=), readJSON, readProp, write)
9+
import Data.Foreign (F, Foreign, readNumber)
10+
import Data.Foreign.Index ((!))
1111

12-
-- | To parse objects of a particular type, we need to define some helper
13-
-- data types as making class instances for records is not possible.
14-
data Point = Point { x :: Number, y :: Number }
12+
import Example.Util.Value (foreignValue)
13+
14+
newtype Point = Point { x :: Number, y :: Number }
1515

1616
instance showPoint :: Show Point where
17-
show (Point o) = "(Point { x: " <> show o.x <> ", y: " <> show o.y <> " })"
18-
19-
instance pointAsForeign :: AsForeign Point where
20-
write (Point o) = writeObject [ "x" .= o.x
21-
, "y" .= o.y
22-
]
23-
24-
-- | The IsForeign implementations for these types are basically boilerplate,
25-
-- type inference takes care of most of the work so we don't have to
26-
-- explicitly define the type each of the properties we're parsing.
27-
instance pointIsForeign :: IsForeign Point where
28-
read value = do
29-
x <- readProp "x" value
30-
y <- readProp "y" value
31-
pure $ Point { x: x, y: y }
17+
show (Point { x, y }) =
18+
"(Point { x: " <> show x <> ", y: " <> show y <> " })"
19+
20+
readPoint :: Foreign -> F Point
21+
readPoint value = do
22+
x <- value ! "x" >>= readNumber
23+
y <- value ! "y" >>= readNumber
24+
pure $ Point { x, y }
3225

3326
main :: Eff (console :: CONSOLE) Unit
3427
main = do
35-
logShow $ runExcept $ readJSON """{ "x": 1, "y": 2 }""" :: F Point
36-
log $ unsafeFromForeign $ write $ Point { x: 1.0, y: 2.0 }
28+
logShow $ runExcept $
29+
readPoint =<< foreignValue """{ "x": 1, "y": 2 }"""

examples/ParseErrors.purs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,40 @@ import Control.Monad.Eff (Eff)
66
import Control.Monad.Eff.Console (CONSOLE, logShow)
77
import Control.Monad.Except (runExcept)
88

9-
import Data.Foreign (F)
10-
import Data.Foreign.Class (class IsForeign, readJSON, readProp)
9+
import Data.Foreign (F, Foreign, readArrayWith, readBoolean, readNumber, readString)
10+
import Data.Foreign.Index ((!))
1111

12-
-- | See the `Objects` example for an explanation of how to parse objects
13-
-- like this.
14-
data Point = Point { x :: Number, y :: Number }
12+
import Example.Util.Value (foreignValue)
13+
14+
newtype Point = Point { x :: Number, y :: Number }
1515

1616
instance showPoint :: Show Point where
1717
show (Point o) = "(Point { x: " <> show o.x <> ", y: " <> show o.y <> " })"
1818

19-
instance pointIsForeign :: IsForeign Point where
20-
read value = do
21-
x <- readProp "x" value
22-
y <- readProp "y" value
23-
pure $ Point { x: x, y: y }
19+
readPoint :: Foreign -> F Point
20+
readPoint value = do
21+
x <- value ! "x" >>= readNumber
22+
y <- value ! "y" >>= readNumber
23+
pure $ Point { x: x, y: y }
2424

2525
main :: Eff (console :: CONSOLE) Unit
2626
main = do
2727

2828
-- When trying to parse invalid JSON we catch an exception from
2929
-- `JSON.parse` and pass it on.
30-
logShow $ runExcept $ readJSON "not even JSON" :: F String
30+
logShow $ runExcept $
31+
readString =<< foreignValue "not even JSON"
3132

3233
-- When attempting to coerce one type to another we get an error.
33-
logShow $ runExcept $ readJSON "26" :: F Boolean
34+
logShow $ runExcept $
35+
readBoolean =<< foreignValue "26"
3436

3537
-- When parsing fails in an array, we're told at which index the value that
3638
-- failed to parse was, along with the reason the value didn't parse.
37-
logShow $ runExcept $ readJSON "[1, true, 3]" :: F (Array Boolean)
39+
logShow $ runExcept $
40+
readArrayWith readBoolean =<< foreignValue "[1, true, 3]"
3841

3942
-- When parsing fails in an object, we're the name of the property which
4043
-- failed to parse was, along with the reason the value didn't parse.
41-
logShow $ runExcept $ readJSON """{ "x": 1, "y": false }""" :: F Point
44+
logShow $ runExcept $
45+
readPoint =<< foreignValue """{ "x": 1, "y": false }"""

0 commit comments

Comments
 (0)